commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 03/25: polar: SC and SC List decoder implem


From: git
Subject: [Commit-gnuradio] [gnuradio] 03/25: polar: SC and SC List decoder implemented in C++
Date: Wed, 23 Sep 2015 14:51:36 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit 13592802e792a417b1db511dbb1d0445ff4955c8
Author: Johannes Demel <address@hidden>
Date:   Thu Jun 18 12:14:32 2015 +0200

    polar: SC and SC List decoder implemented in C++
---
 gr-fec/examples/polar_encoder_decoder_chain.grc    | 350 ++++++++++-----------
 gr-fec/grc/fec_block_tree.xml                      |   2 +
 gr-fec/grc/fec_polar_decoder_sc.xml                |  50 +++
 gr-fec/grc/fec_polar_decoder_sc_list.xml           |  57 ++++
 gr-fec/include/gnuradio/fec/CMakeLists.txt         |   6 +-
 gr-fec/include/gnuradio/fec/polar_common.h         |  83 +++++
 gr-fec/include/gnuradio/fec/polar_decoder_common.h |  87 +++++
 gr-fec/include/gnuradio/fec/polar_decoder_sc.h     |  65 ++++
 .../include/gnuradio/fec/polar_decoder_sc_list.h   |  69 ++++
 gr-fec/include/gnuradio/fec/polar_encoder.h        |  31 +-
 gr-fec/lib/CMakeLists.txt                          |   7 +-
 gr-fec/lib/polar_common.cc                         | 139 ++++++++
 gr-fec/lib/polar_decoder_common.cc                 | 209 ++++++++++++
 gr-fec/lib/polar_decoder_sc.cc                     |  99 ++++++
 gr-fec/lib/polar_decoder_sc_list.cc                | 123 ++++++++
 gr-fec/lib/polar_encoder.cc                        | 162 ++++------
 gr-fec/lib/scl_list.cc                             | 191 +++++++++++
 gr-fec/lib/scl_list.h                              |  83 +++++
 .../python/fec/polar/channel_construction_bec.py   |   6 +
 .../python/fec/polar/channel_construction_bsc.py   |  17 -
 gr-fec/python/fec/polar/decoder.py                 |  15 +-
 gr-fec/python/fec/polar/helper_functions.py        |   6 +-
 gr-fec/python/fec/polar/testbed.py                 |  23 +-
 gr-fec/python/fec/qa_polar_decoder_sc.py           | 152 +++++++++
 gr-fec/python/fec/qa_polar_decoder_sc_list.py      | 157 +++++++++
 gr-fec/python/fec/qa_polar_encoder.py              |  23 +-
 gr-fec/swig/fec_swig.i                             |   8 +
 27 files changed, 1865 insertions(+), 355 deletions(-)

diff --git a/gr-fec/examples/polar_encoder_decoder_chain.grc 
b/gr-fec/examples/polar_encoder_decoder_chain.grc
index c648aea..7cab62d 100644
--- a/gr-fec/examples/polar_encoder_decoder_chain.grc
+++ b/gr-fec/examples/polar_encoder_decoder_chain.grc
@@ -18,7 +18,17 @@
     </param>
     <param>
       <key>comment</key>
-      <value></value>
+      <value># for rough throughput measurements.
+
+    tb = polar_encoder_decoder_chain()
+    start_time = time.time()
+    tb.start()
+    tb.wait()
+    stop_time = time.time()
+    samps = 2 ** 22
+    diff = stop_time - start_time
+    throughput = tb.head_samps / diff
+    print("exe time:", diff, ", with ", tb.head_samps, "samps, throughput: ", 
throughput)</value>
     </param>
     <param>
       <key>description</key>
@@ -74,42 +84,18 @@
     </param>
   </block>
   <block>
-    <key>variable_cc_decoder_def</key>
-    <param>
-      <key>padding</key>
-      <value>False</value>
-    </param>
+    <key>variable</key>
     <param>
       <key>comment</key>
       <value></value>
     </param>
     <param>
-      <key>k</key>
-      <value>7</value>
-    </param>
-    <param>
-      <key>dim1</key>
-      <value>1</value>
-    </param>
-    <param>
-      <key>dim2</key>
-      <value>1</value>
-    </param>
-    <param>
       <key>_enabled</key>
       <value>True</value>
     </param>
     <param>
-      <key>state_end</key>
-      <value>-1</value>
-    </param>
-    <param>
-      <key>framebits</key>
-      <value>2048</value>
-    </param>
-    <param>
       <key>_coordinate</key>
-      <value>(640, 35)</value>
+      <value>(360, 11)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -117,66 +103,42 @@
     </param>
     <param>
       <key>id</key>
-      <value>cc_decoder</value>
+      <value>head_samps</value>
     </param>
     <param>
       <key>value</key>
-      <value>"ok"</value>
-    </param>
-    <param>
-      <key>ndim</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>polys</key>
-      <value>[79,109]</value>
-    </param>
-    <param>
-      <key>rate</key>
-      <value>2</value>
-    </param>
-    <param>
-      <key>state_start</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>mode</key>
-      <value>fec.CC_STREAMING</value>
+      <value>2 ** 22</value>
     </param>
   </block>
   <block>
-    <key>variable_cc_encoder_def</key>
+    <key>variable_polar_decoder_sc_def</key>
     <param>
-      <key>padding</key>
-      <value>False</value>
-    </param>
-    <param>
-      <key>comment</key>
-      <value></value>
+      <key>num_info_bits</key>
+      <value>128</value>
     </param>
     <param>
-      <key>k</key>
-      <value>7</value>
+      <key>block_size</key>
+      <value>256</value>
     </param>
     <param>
-      <key>dim1</key>
-      <value>1</value>
+      <key>comment</key>
+      <value></value>
     </param>
     <param>
-      <key>dim2</key>
-      <value>1</value>
+      <key>_enabled</key>
+      <value>True</value>
     </param>
     <param>
-      <key>_enabled</key>
-      <value>False</value>
+      <key>frozen_bit_positions</key>
+      <value>range(128)</value>
     </param>
     <param>
-      <key>framebits</key>
-      <value>2048</value>
+      <key>frozen_bit_values</key>
+      <value>[0] * 128</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(304, 43)</value>
+      <value>(864, 555)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -184,27 +146,11 @@
     </param>
     <param>
       <key>id</key>
-      <value>cc_encoder</value>
-    </param>
-    <param>
-      <key>ndim</key>
-      <value>0</value>
-    </param>
-    <param>
-      <key>polys</key>
-      <value>[79,109]</value>
-    </param>
-    <param>
-      <key>rate</key>
-      <value>2</value>
-    </param>
-    <param>
-      <key>state_start</key>
-      <value>0</value>
+      <value>polar_decoder</value>
     </param>
     <param>
-      <key>mode</key>
-      <value>fec.CC_STREAMING</value>
+      <key>is_packed</key>
+      <value>False</value>
     </param>
   </block>
   <block>
@@ -235,7 +181,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(576, 307)</value>
+      <value>(192, 451)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -251,7 +197,15 @@
     </param>
   </block>
   <block>
-    <key>variable</key>
+    <key>variable_polar_decoder_sc_list_def</key>
+    <param>
+      <key>num_info_bits</key>
+      <value>128</value>
+    </param>
+    <param>
+      <key>block_size</key>
+      <value>256</value>
+    </param>
     <param>
       <key>comment</key>
       <value></value>
@@ -261,8 +215,16 @@
       <value>True</value>
     </param>
     <param>
+      <key>frozen_bit_positions</key>
+      <value>range(128)</value>
+    </param>
+    <param>
+      <key>frozen_bit_values</key>
+      <value>[0,] * 128</value>
+    </param>
+    <param>
       <key>_coordinate</key>
-      <value>(10, 170)</value>
+      <value>(608, 539)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -270,11 +232,15 @@
     </param>
     <param>
       <key>id</key>
-      <value>samp_rate</value>
+      <value>polar_scld</value>
     </param>
     <param>
-      <key>value</key>
-      <value>32000</value>
+      <key>max_list_size</key>
+      <value>8</value>
+    </param>
+    <param>
+      <key>is_packed</key>
+      <value>False</value>
     </param>
   </block>
   <block>
@@ -297,7 +263,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(136, 227)</value>
+      <value>(0, 323)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -325,7 +291,7 @@
     </param>
     <param>
       <key>num_samps</key>
-      <value>2 ** 10</value>
+      <value>2 ** 10 </value>
     </param>
     <param>
       <key>type</key>
@@ -337,7 +303,7 @@
     </param>
   </block>
   <block>
-    <key>blocks_char_to_float</key>
+    <key>blocks_add_const_vxx</key>
     <param>
       <key>alias</key>
       <value></value>
@@ -347,16 +313,20 @@
       <value></value>
     </param>
     <param>
+      <key>const</key>
+      <value>1.0</value>
+    </param>
+    <param>
       <key>affinity</key>
       <value></value>
     </param>
     <param>
       <key>_enabled</key>
-      <value>False</value>
+      <value>True</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1272, 251)</value>
+      <value>(752, 347)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -364,7 +334,11 @@
     </param>
     <param>
       <key>id</key>
-      <value>blocks_char_to_float_0</value>
+      <value>blocks_add_const_vxx_0</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>float</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -375,16 +349,12 @@
       <value>0</value>
     </param>
     <param>
-      <key>scale</key>
-      <value>10</value>
-    </param>
-    <param>
       <key>vlen</key>
       <value>1</value>
     </param>
   </block>
   <block>
-    <key>blocks_head</key>
+    <key>blocks_char_to_float</key>
     <param>
       <key>alias</key>
       <value></value>
@@ -399,11 +369,11 @@
     </param>
     <param>
       <key>_enabled</key>
-      <value>True</value>
+      <value>False</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1080, 363)</value>
+      <value>(1112, 347)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -411,7 +381,7 @@
     </param>
     <param>
       <key>id</key>
-      <value>blocks_head_0</value>
+      <value>blocks_char_to_float_0</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -422,12 +392,8 @@
       <value>0</value>
     </param>
     <param>
-      <key>num_items</key>
-      <value>2 ** 32</value>
-    </param>
-    <param>
-      <key>type</key>
-      <value>byte</value>
+      <key>scale</key>
+      <value>1.0</value>
     </param>
     <param>
       <key>vlen</key>
@@ -435,16 +401,12 @@
     </param>
   </block>
   <block>
-    <key>blocks_null_sink</key>
+    <key>blocks_char_to_float</key>
     <param>
       <key>alias</key>
       <value></value>
     </param>
     <param>
-      <key>bus_conns</key>
-      <value>[[0,],]</value>
-    </param>
-    <param>
       <key>comment</key>
       <value></value>
     </param>
@@ -458,7 +420,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1256, 368)</value>
+      <value>(616, 347)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -466,15 +428,19 @@
     </param>
     <param>
       <key>id</key>
-      <value>blocks_null_sink_0</value>
+      <value>blocks_char_to_float_0_0</value>
     </param>
     <param>
-      <key>type</key>
-      <value>byte</value>
+      <key>maxoutbuf</key>
+      <value>0</value>
     </param>
     <param>
-      <key>num_inputs</key>
-      <value>1</value>
+      <key>minoutbuf</key>
+      <value>0</value>
+    </param>
+    <param>
+      <key>scale</key>
+      <value>-0.5</value>
     </param>
     <param>
       <key>vlen</key>
@@ -482,7 +448,7 @@
     </param>
   </block>
   <block>
-    <key>blocks_pack_k_bits_bb</key>
+    <key>blocks_head</key>
     <param>
       <key>alias</key>
       <value></value>
@@ -501,7 +467,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(408, 251)</value>
+      <value>(944, 459)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -509,11 +475,7 @@
     </param>
     <param>
       <key>id</key>
-      <value>blocks_pack_k_bits_bb_0</value>
-    </param>
-    <param>
-      <key>k</key>
-      <value>8</value>
+      <value>blocks_head_0</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -523,14 +485,30 @@
       <key>minoutbuf</key>
       <value>0</value>
     </param>
+    <param>
+      <key>num_items</key>
+      <value>head_samps</value>
+    </param>
+    <param>
+      <key>type</key>
+      <value>byte</value>
+    </param>
+    <param>
+      <key>vlen</key>
+      <value>1</value>
+    </param>
   </block>
   <block>
-    <key>blocks_unpack_k_bits_bb</key>
+    <key>blocks_null_sink</key>
     <param>
       <key>alias</key>
       <value></value>
     </param>
     <param>
+      <key>bus_conns</key>
+      <value>[[0,],]</value>
+    </param>
+    <param>
       <key>comment</key>
       <value></value>
     </param>
@@ -544,7 +522,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(904, 363)</value>
+      <value>(1160, 464)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -552,23 +530,27 @@
     </param>
     <param>
       <key>id</key>
-      <value>blocks_unpack_k_bits_bb_0</value>
+      <value>blocks_null_sink_0</value>
     </param>
     <param>
-      <key>k</key>
-      <value>8</value>
+      <key>type</key>
+      <value>byte</value>
     </param>
     <param>
-      <key>maxoutbuf</key>
-      <value>0</value>
+      <key>num_inputs</key>
+      <value>1</value>
     </param>
     <param>
-      <key>minoutbuf</key>
-      <value>0</value>
+      <key>vlen</key>
+      <value>1</value>
     </param>
   </block>
   <block>
-    <key>fec_generic_decoder</key>
+    <key>fec_extended_decoder</key>
+    <param>
+      <key>ann</key>
+      <value>None</value>
+    </param>
     <param>
       <key>alias</key>
       <value></value>
@@ -582,16 +564,16 @@
       <value></value>
     </param>
     <param>
-      <key>decoder</key>
-      <value>cc_decoder</value>
+      <key>decoder_list</key>
+      <value>polar_scld</value>
     </param>
     <param>
       <key>_enabled</key>
-      <value>False</value>
+      <value>True</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1040, 251)</value>
+      <value>(872, 323)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -599,11 +581,7 @@
     </param>
     <param>
       <key>id</key>
-      <value>fec_generic_decoder_0</value>
-    </param>
-    <param>
-      <key>itype</key>
-      <value>byte</value>
+      <value>fec_extended_decoder_0</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -614,12 +592,20 @@
       <value>0</value>
     </param>
     <param>
-      <key>otype</key>
-      <value>byte</value>
+      <key>puncpat</key>
+      <value>'11'</value>
+    </param>
+    <param>
+      <key>threadtype</key>
+      <value>none</value>
+    </param>
+    <param>
+      <key>value</key>
+      <value>fec_extended_decoder</value>
     </param>
   </block>
   <block>
-    <key>fec_generic_encoder</key>
+    <key>fec_extended_encoder</key>
     <param>
       <key>alias</key>
       <value></value>
@@ -629,20 +615,20 @@
       <value></value>
     </param>
     <param>
-      <key>encoder</key>
-      <value>polar_encoder</value>
-    </param>
-    <param>
       <key>affinity</key>
       <value></value>
     </param>
     <param>
       <key>_enabled</key>
-      <value>True</value>
+      <value>False</value>
+    </param>
+    <param>
+      <key>encoder_list</key>
+      <value>polar_encoder</value>
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(576, 251)</value>
+      <value>(192, 331)</value>
     </param>
     <param>
       <key>_rotation</key>
@@ -650,11 +636,7 @@
     </param>
     <param>
       <key>id</key>
-      <value>fec_generic_encoder_0</value>
-    </param>
-    <param>
-      <key>itype</key>
-      <value>byte</value>
+      <value>fec_extended_encoder_0</value>
     </param>
     <param>
       <key>maxoutbuf</key>
@@ -665,8 +647,12 @@
       <value>0</value>
     </param>
     <param>
-      <key>otype</key>
-      <value>byte</value>
+      <key>puncpat</key>
+      <value>'11'</value>
+    </param>
+    <param>
+      <key>threadtype</key>
+      <value>none</value>
     </param>
   </block>
   <block>
@@ -732,7 +718,7 @@
     </param>
     <param>
       <key>_coordinate</key>
-      <value>(1432, 235)</value>
+      <value>(1256, 331)</value>
     </param>
     <param>
       <key>gui_hint</key>
@@ -1061,55 +1047,55 @@
   </block>
   <connection>
     <source_block_id>analog_random_source_x_0</source_block_id>
-    <sink_block_id>blocks_pack_k_bits_bb_0</sink_block_id>
+    <sink_block_id>blocks_char_to_float_0_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>blocks_char_to_float_0</source_block_id>
-    <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
+    <source_block_id>analog_random_source_x_0</source_block_id>
+    <sink_block_id>fec_extended_encoder_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>blocks_head_0</source_block_id>
-    <sink_block_id>blocks_null_sink_0</sink_block_id>
+    <source_block_id>blocks_add_const_vxx_0</source_block_id>
+    <sink_block_id>fec_extended_decoder_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>blocks_pack_k_bits_bb_0</source_block_id>
-    <sink_block_id>fec_generic_encoder_0</sink_block_id>
+    <source_block_id>blocks_char_to_float_0</source_block_id>
+    <sink_block_id>qtgui_time_sink_x_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>blocks_unpack_k_bits_bb_0</source_block_id>
-    <sink_block_id>blocks_head_0</sink_block_id>
+    <source_block_id>blocks_char_to_float_0_0</source_block_id>
+    <sink_block_id>blocks_add_const_vxx_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>fec_generic_decoder_0</source_block_id>
-    <sink_block_id>blocks_char_to_float_0</sink_block_id>
+    <source_block_id>blocks_head_0</source_block_id>
+    <sink_block_id>blocks_null_sink_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>fec_generic_encoder_0</source_block_id>
+    <source_block_id>fec_extended_decoder_0</source_block_id>
     <sink_block_id>blocks_char_to_float_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>fec_generic_encoder_0</source_block_id>
-    <sink_block_id>blocks_unpack_k_bits_bb_0</sink_block_id>
+    <source_block_id>fec_extended_decoder_0</source_block_id>
+    <sink_block_id>blocks_head_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
   <connection>
-    <source_block_id>fec_generic_encoder_0</source_block_id>
-    <sink_block_id>fec_generic_decoder_0</sink_block_id>
+    <source_block_id>fec_extended_encoder_0</source_block_id>
+    <sink_block_id>blocks_char_to_float_0_0</sink_block_id>
     <source_key>0</source_key>
     <sink_key>0</sink_key>
   </connection>
diff --git a/gr-fec/grc/fec_block_tree.xml b/gr-fec/grc/fec_block_tree.xml
index f2f2c5b..d15ef26 100644
--- a/gr-fec/grc/fec_block_tree.xml
+++ b/gr-fec/grc/fec_block_tree.xml
@@ -15,6 +15,8 @@
       <block>variable_ldpc_decoder_def</block>
       <block>variable_tpc_decoder_def</block>
       <block>variable_dummy_decoder_def</block>
+      <block>variable_polar_decoder_sc_def</block>
+      <block>variable_polar_decoder_sc_list_def</block>
     </cat>
     <cat>
       <name>Encoders</name>
diff --git a/gr-fec/grc/fec_polar_decoder_sc.xml 
b/gr-fec/grc/fec_polar_decoder_sc.xml
new file mode 100644
index 0000000..e7cb1ea
--- /dev/null
+++ b/gr-fec/grc/fec_polar_decoder_sc.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<block>
+  <name>POLAR Decoder SC Definition</name>
+  <key>variable_polar_decoder_sc_def</key>
+  <import>from gnuradio import fec</import>
+  <var_make>
+self.$(id) = $(id) = fec.polar_decoder_sc.make($block_size, $num_info_bits, 
$frozen_bit_positions, $frozen_bit_values, $is_packed)
+  </var_make>
+  <var_value>fec.polar_decoder_sc.make($block_size, $num_info_bits, 
$frozen_bit_positions, $frozen_bit_values, $is_packed)</var_value>
+  <make></make>
+
+  <param>
+    <name>Packed Bits</name>
+    <key>is_packed</key>
+    <value>False</value>
+    <type>enum</type>
+    <option>
+      <name>No</name>
+      <key>False</key>
+    </option>
+    <option>
+      <name>Yes</name>
+      <key>True</key>
+    </option>
+  </param>
+
+  <param>
+    <name>Block size (N)</name>
+    <key>block_size</key>
+    <type>int</type>
+  </param>
+
+  <param>
+    <name>#Info Bits (K)</name>
+    <key>num_info_bits</key>
+    <type>int</type>
+  </param>
+
+  <param>
+    <name>Frozen Bit Positions</name>
+    <key>frozen_bit_positions</key>
+    <type>int_vector</type>
+  </param>
+
+  <param>
+    <name>Frozen Bit Values</name>
+    <key>frozen_bit_values</key>
+    <type>int_vector</type>
+  </param>
+</block>
diff --git a/gr-fec/grc/fec_polar_decoder_sc_list.xml 
b/gr-fec/grc/fec_polar_decoder_sc_list.xml
new file mode 100644
index 0000000..fa8208f
--- /dev/null
+++ b/gr-fec/grc/fec_polar_decoder_sc_list.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<block>
+  <name>POLAR Decoder SC List Definition</name>
+  <key>variable_polar_decoder_sc_list_def</key>
+  <import>from gnuradio import fec</import>
+  <var_make>
+self.$(id) = $(id) = fec.polar_decoder_sc_list.make($max_list_size, 
$block_size, $num_info_bits, $frozen_bit_positions, $frozen_bit_values, 
$is_packed)
+  </var_make>
+  <var_value>fec.polar_decoder_sc_list.make($max_list_size, $block_size, 
$num_info_bits, $frozen_bit_positions, $frozen_bit_values, 
$is_packed)</var_value>
+  <make></make>
+
+
+  <param>
+    <name>Packed Bits</name>
+    <key>is_packed</key>
+    <value>False</value>
+    <type>enum</type>
+    <option>
+      <name>No</name>
+      <key>False</key>
+    </option>
+    <option>
+      <name>Yes</name>
+      <key>True</key>
+    </option>
+  </param>
+
+  <param>
+    <name>Maximum List Size (L)</name>
+    <key>max_list_size</key>
+    <type>int</type>
+  </param>
+
+  <param>
+    <name>Block size (N)</name>
+    <key>block_size</key>
+    <type>int</type>
+  </param>
+
+  <param>
+    <name>#Info Bits (K)</name>
+    <key>num_info_bits</key>
+    <type>int</type>
+  </param>
+
+  <param>
+    <name>Frozen Bit Positions</name>
+    <key>frozen_bit_positions</key>
+    <type>int_vector</type>
+  </param>
+
+  <param>
+    <name>Frozen Bit Values</name>
+    <key>frozen_bit_values</key>
+    <type>int_vector</type>
+  </param>
+</block>
diff --git a/gr-fec/include/gnuradio/fec/CMakeLists.txt 
b/gr-fec/include/gnuradio/fec/CMakeLists.txt
index 0b3a5a3..1078225 100644
--- a/gr-fec/include/gnuradio/fec/CMakeLists.txt
+++ b/gr-fec/include/gnuradio/fec/CMakeLists.txt
@@ -47,6 +47,10 @@ install(FILES
     puncture_bb.h
     puncture_ff.h
     depuncture_bb.h
-    polar_encoder.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec
+    polar_encoder.h
+    polar_decoder_sc.h
+    polar_common.h
+    polar_decoder_sc_list.h
+    polar_decoder_common.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/fec
     COMPONENT "fec_devel"
 )
diff --git a/gr-fec/include/gnuradio/fec/polar_common.h 
b/gr-fec/include/gnuradio/fec/polar_common.h
new file mode 100644
index 0000000..59e0ad3
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_common.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FEC_POLAR_COMMON_H
+#define INCLUDED_FEC_POLAR_COMMON_H
+
+#include <gnuradio/fec/api.h>
+
+// Forward declaration for those objects. SWIG doesn't like them to be 
#include'd.
+namespace gr {
+  namespace blocks {
+    namespace kernel {
+      class pack_k_bits;
+      class unpack_k_bits;
+    }
+  }
+}
+
+namespace gr {
+  namespace fec {
+
+    /*!
+     * \brief POLAR code common operations and attributes
+     * Erdal Arikan "Channel Polarization: A Method for Contructing 
Capacity-Achieving Codes for Symmetric Binary-Input Memoryless Channels", 2009
+     */
+    class FEC_API polar_common
+    {
+    public:
+      polar_common(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed = 
false);
+      ~polar_common();
+
+    protected:
+      const int block_size()const {return d_block_size;};
+      const int block_power()const {return d_block_power;};
+      const int num_info_bits() const {return d_num_info_bits;};
+      const bool is_packed() const {return d_is_packed;};
+
+      // helper functions
+      long bit_reverse(long value, int active_bits) const;
+      void print_packed_bit_array(const unsigned char* printed_array, const 
int num_bytes) const;
+      void print_unpacked_bit_array(const unsigned char* bits, const unsigned 
int num_bytes) const;
+      const gr::blocks::kernel::unpack_k_bits* unpacker() const {return 
d_unpacker;};
+      std::vector<int> info_bit_position_vector();
+
+    private:
+      int d_block_size; // depending on paper called 'N' or 'm'
+      int d_block_power;
+      int d_num_info_bits; // mostly abbreviated by 'K'
+      bool d_is_packed;
+      std::vector<int> d_frozen_bit_positions;
+      std::vector<int> d_info_bit_positions;
+      std::vector<char> d_frozen_bit_values;
+      void initialize_info_bit_position_vector();
+
+      gr::blocks::kernel::pack_k_bits *d_packer;
+      gr::blocks::kernel::unpack_k_bits *d_unpacker;
+    };
+
+  } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_COMMON_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_common.h 
b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
new file mode 100644
index 0000000..50003b6
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_common.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FEC_POLAR_DECODER_COMMON_H
+#define INCLUDED_FEC_POLAR_DECODER_COMMON_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/generic_decoder.h>
+#include <gnuradio/fec/polar_common.h>
+
+namespace gr {
+  namespace fec {
+
+    /*!
+     * \brief Class holds common methods and attributes for different decoder 
implementations
+     *
+     */
+    class FEC_API polar_decoder_common : public generic_decoder, public 
polar_common
+    {
+    public:
+      polar_decoder_common(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+      ~polar_decoder_common();
+
+      // FECAPI
+      double rate(){return (1.0 * get_input_size() / get_output_size());};
+      int get_input_size(){return block_size() / (is_packed() ? 8 : 1);};
+      int get_output_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
+      bool set_frame_size(unsigned int frame_size){return false;};
+      const char* get_output_conversion() {return "none";};
+
+    private:
+      const float D_LLR_FACTOR;
+
+    protected:
+      // calculate LLRs for stage
+      float llr_odd(const float la, const float lb) const;
+      float llr_even(const float la, const float lb, const unsigned char f) 
const;
+      unsigned char llr_bit_decision(const float llr) const {return (llr < 
0.0f) ? 1 : 0;};
+
+      // preparation for decoding
+      void initialize_llr_vector(float* llrs, const float* input);
+      // basic algorithm methods
+      void butterfly(float* llrs, const int stage, unsigned char* u, const int 
u_num);
+      void even_u_values(unsigned char* u_even, const unsigned char* u, const 
int u_num);
+      void odd_xor_even_values(unsigned char* u_xor, const unsigned char* u, 
const int u_num);
+      void demortonize_values(unsigned char* u);
+
+      void extract_info_bits(unsigned char* output, const unsigned char* 
input) const;
+
+      static void insert_bit_at_pos(unsigned char* u, const unsigned char ui, 
const unsigned int pos){u[pos >> 3] ^= ui << (7 - (pos % 8));};
+      static unsigned char fetch_bit_at_pos(const unsigned char* u, const 
unsigned int pos){return (u[pos >> 3] >> (7 - (pos % 8))) & 0x01;};
+
+      // info shared among all implementations.
+      std::vector<int> d_frozen_bit_positions;
+      std::vector<int> d_info_bit_positions;
+      std::vector<char> d_frozen_bit_values;
+
+      // helper functions.
+      void print_pretty_llr_vector(const float* llr_vec) const;
+
+    };
+
+  } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_DECODER_COMMON_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc.h 
b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
new file mode 100644
index 0000000..d9aa959
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_FEC_POLAR_DECODER_SC_H
+#define INCLUDED_FEC_POLAR_DECODER_SC_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/polar_decoder_common.h>
+
+
+namespace gr {
+  namespace fec {
+
+    /*!
+     * \brief Standard successive cancellation decoder for POLAR codes
+     * It expects float input with bits mapped 1 --> -1, 0 --> 1
+     * Or: f = 1.0 - 2.0 * bit
+     *
+     */
+    class FEC_API polar_decoder_sc : public polar_decoder_common
+    {
+    public:
+      static generic_decoder::sptr make(int block_size, int num_info_bits, 
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, 
bool is_packed = false);
+      ~polar_decoder_sc();
+
+      // FECAPI
+      void generic_work(void *in_buffer, void *out_buffer);
+
+    private:
+      polar_decoder_sc(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
+
+      unsigned int d_frozen_bit_counter;
+
+      float* d_llr_vec;
+      unsigned char* d_u_hat_vec;
+
+      unsigned char retrieve_bit_from_llr(float llr, const int pos);
+      void sc_decode(float* llrs, unsigned char* u);
+    };
+
+  } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_FEC_POLAR_DECODER_SC_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h 
b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
new file mode 100644
index 0000000..001ef66
--- /dev/null
+++ b/gr-fec/include/gnuradio/fec/polar_decoder_sc_list.h
@@ -0,0 +1,69 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+#ifndef INCLUDED_POLAR_FEC_DECODER_SC_LIST_H
+#define INCLUDED_POLAR_FEC_DECODER_SC_LIST_H
+
+#include <gnuradio/fec/api.h>
+#include <gnuradio/fec/polar_decoder_common.h>
+
+namespace gr {
+  namespace fec {
+    namespace polar {
+      class scl_list;
+      class path;
+    }
+
+    /*!
+     * \brief implements a successive cancellation list decoder for polar codes
+     * decoder is based on Tal, Vardy "List Decoding of Polar Codes", 2012
+     * LLR version: Balatsoukas-Stimming, Parizi, Burg "LLR-based Successive 
Cancellation List Decoding of Polar Codes", 2015
+     *
+     */
+    class FEC_API polar_decoder_sc_list : public polar_decoder_common
+    {
+    public:
+      static generic_decoder::sptr make(int max_list_size, int block_size, int 
num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> 
frozen_bit_values, bool is_packed = false);
+      ~polar_decoder_sc_list();
+
+      // FECAPI
+      void generic_work(void *in_buffer, void *out_buffer);
+
+    private:
+      polar_decoder_sc_list(int max_list_size, int block_size, int 
num_info_bits, std::vector<int> frozen_bit_positions, std::vector<char> 
frozen_bit_values, bool is_packed);
+
+      unsigned int d_max_list_size;
+      polar::scl_list* d_scl;
+      unsigned int d_frozen_bit_counter;
+
+      void decode_list();
+      void calculate_next_llr_in_paths(int u_num);
+      void calculate_next_llr(polar::path* current_path, int u_num);
+      void update_with_frozenbit(const int u_num);
+
+    };
+  } // namespace fec
+} // namespace gr
+
+#endif /* INCLUDED_POLAR_FEC_DECODER_SC_LIST_H */
+
diff --git a/gr-fec/include/gnuradio/fec/polar_encoder.h 
b/gr-fec/include/gnuradio/fec/polar_encoder.h
index 9cd37b8..85208bf 100644
--- a/gr-fec/include/gnuradio/fec/polar_encoder.h
+++ b/gr-fec/include/gnuradio/fec/polar_encoder.h
@@ -26,16 +26,7 @@
 
 #include <gnuradio/fec/api.h>
 #include <gnuradio/fec/generic_encoder.h>
-
-// Forward declaration for those objects. SWIG doesn't like them to be 
#include'd.
-namespace gr {
-  namespace blocks {
-    namespace kernel {
-      class pack_k_bits;
-      class unpack_k_bits;
-    }
-  }
-}
+#include <gnuradio/fec/polar_common.h>
 
 namespace gr {
   namespace fec {
@@ -44,7 +35,7 @@ namespace gr {
      * \brief POLAR encoder
      *
      */
-    class FEC_API polar_encoder : public generic_encoder
+    class FEC_API polar_encoder : public generic_encoder, public polar_common
     {
     public:
       static generic_encoder::sptr make(int block_size, int num_info_bits, 
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, 
bool is_packed = false);
@@ -53,17 +44,14 @@ namespace gr {
       // FECAPI
       void generic_work(void *in_buffer, void *out_buffer);
       double rate(){return (1.0 * get_input_size() / get_output_size());};
-      int get_input_size(){return d_input_size;};
-      int get_output_size(){return d_output_size;};
+      int get_input_size(){return num_info_bits() / (is_packed() ? 8 : 1);};
+      int get_output_size(){return block_size() / (is_packed() ? 8 : 1);};
       bool set_frame_size(unsigned int frame_size){return false;};
+      const char* get_input_conversion(){return is_packed() ? "pack" : 
"none";};
+      const char* get_output_conversion(){return is_packed() ? "packed_bits" : 
"none";};
 
     private:
       polar_encoder(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions, std::vector<char> frozen_bit_values, bool is_packed);
-      int d_block_size; // depending on paper called 'N' or 'm'
-      int d_block_power;
-      int d_input_size, d_output_size;
-      bool d_is_packed;
-      int d_num_info_bits; // mostly abbreviated by 'K'
       std::vector<int> d_frozen_bit_positions;
       std::vector<int> d_info_bit_positions;
       std::vector<char> d_frozen_bit_values;
@@ -90,13 +78,6 @@ namespace gr {
       void encode_packed_byte(unsigned char* target) const;
       void encode_vector_packed_interbyte(unsigned char* target) const;
 
-      // helper functions
-      long bit_reverse(long value, int active_bits) const;
-      void print_packed_bit_array(const unsigned char* printed_array, const 
int num_bytes) const;
-
-      gr::blocks::kernel::pack_k_bits *d_packer;
-      gr::blocks::kernel::unpack_k_bits *d_unpacker;
-
     };
 
   } // namespace fec
diff --git a/gr-fec/lib/CMakeLists.txt b/gr-fec/lib/CMakeLists.txt
index 00cb061..0343ce3 100644
--- a/gr-fec/lib/CMakeLists.txt
+++ b/gr-fec/lib/CMakeLists.txt
@@ -81,7 +81,12 @@ list(APPEND gnuradio_fec_sources
   tpc_common.cc
   tpc_decoder.cc
   tpc_encoder.cc
-    polar_encoder.cc
+  polar_encoder.cc
+  polar_decoder_sc.cc
+  polar_common.cc
+  polar_decoder_sc_list.cc
+  polar_decoder_common.cc
+  scl_list.cc
 )
 
 #Add Windows DLL resource file if using MSVC
diff --git a/gr-fec/lib/polar_common.cc b/gr-fec/lib/polar_common.cc
new file mode 100644
index 0000000..c76f530
--- /dev/null
+++ b/gr-fec/lib/polar_common.cc
@@ -0,0 +1,139 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include <gnuradio/fec/polar_common.h>
+
+#include <gnuradio/blocks/pack_k_bits.h>
+#include <gnuradio/blocks/unpack_k_bits.h>
+
+#include <cmath>
+#include <stdexcept>
+#include <iostream>
+#include <vector>
+
+namespace gr
+{
+  namespace fec
+  {
+
+    polar_common::polar_common(int block_size, int num_info_bits,
+                               std::vector<int> frozen_bit_positions,
+                               std::vector<char> frozen_bit_values, bool 
is_packed) :
+        d_block_size(block_size), d_block_power((int) 
log2(float(block_size))), d_num_info_bits(num_info_bits), 
d_is_packed(is_packed),
+            d_frozen_bit_positions(frozen_bit_positions), 
d_frozen_bit_values(frozen_bit_values)
+    {
+      if(pow(2, d_block_power) != d_block_size) {
+        throw std::runtime_error("block_size MUST be a power of 2!");
+      }
+
+      unsigned int num_frozen_bits = d_block_size - d_num_info_bits;
+      if(num_frozen_bits != d_frozen_bit_positions.size()) {
+        throw std::runtime_error(
+            "number of frozen bit positions must equal block_size - 
num_info_bits");
+      }
+
+      // According to papers frozen bits default to '0'.
+      while(d_frozen_bit_values.size() < num_frozen_bits) {
+        d_frozen_bit_values.push_back(0);
+      }
+      initialize_info_bit_position_vector();
+
+      d_packer = new gr::blocks::kernel::pack_k_bits(8);
+      d_unpacker = new gr::blocks::kernel::unpack_k_bits(8);
+    }
+
+
+    std::vector<int>
+    polar_common::info_bit_position_vector()
+    {
+      return d_info_bit_positions;
+    }
+
+    void
+    polar_common::initialize_info_bit_position_vector()
+    {
+      int num_frozen_bit = 0;
+      for(int i = 0; i < block_size(); i++) {
+        int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
+        if(i != frozen_pos) {
+          d_info_bit_positions.push_back((int) i);
+        }
+        else {
+          num_frozen_bit++;
+          num_frozen_bit = std::min(num_frozen_bit, (int) 
(d_frozen_bit_positions.size() - 1));
+        }
+      }
+    }
+
+    polar_common::~polar_common()
+    {
+      delete d_packer;
+      delete d_unpacker;
+    }
+
+    long
+    polar_common::bit_reverse(long value, int active_bits) const
+    {
+      long r = 0;
+      for(int i = 0; i < active_bits; i++) {
+        r <<= 1;
+        r |= value & 1;
+        value >>= 1;
+      }
+      return r;
+    }
+
+    void
+    polar_common::print_packed_bit_array(const unsigned char* printed_array,
+                                          const int num_bytes) const
+    {
+      int num_bits = num_bytes << 3;
+      unsigned char* temp = new unsigned char[num_bits];
+      unpacker()->unpack(temp, printed_array, num_bytes);
+
+      std::cout << "[";
+      for(int i = 0; i < num_bits; i++) {
+        std::cout << (int) *(temp + i) << " ";
+      }
+      std::cout << "]" << std::endl;
+
+      delete [] temp;
+    }
+
+    void
+    polar_common::print_unpacked_bit_array(const unsigned char* bits,
+                                                    const unsigned int 
num_bytes) const
+    {
+      std::cout << "( ";
+      for(unsigned int i = 0; i < num_bytes; i++){
+        std::cout << (int) *bits++ << ", ";
+      }
+      std::cout << ")" << std::endl;
+    }
+
+  } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/polar_decoder_common.cc 
b/gr-fec/lib/polar_decoder_common.cc
new file mode 100644
index 0000000..0285641
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_common.cc
@@ -0,0 +1,209 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include <gnuradio/fec/polar_decoder_common.h>
+#include <volk/volk.h>
+
+#include <cstdio>
+
+#define INT_BIT_MASK 0x80000000
+
+namespace gr {
+  namespace fec {
+
+    polar_decoder_common::polar_decoder_common(int block_size, int 
num_info_bits,
+                                               std::vector<int> 
frozen_bit_positions,
+                                               std::vector<char> 
frozen_bit_values, bool is_packed) :
+        polar_common(block_size, num_info_bits, frozen_bit_positions, 
frozen_bit_values, is_packed),
+        D_LLR_FACTOR(2.19722458f),
+        d_frozen_bit_positions(frozen_bit_positions),
+        d_frozen_bit_values(frozen_bit_values)
+    {
+    }
+
+    polar_decoder_common::~polar_decoder_common()
+    {
+    }
+
+    void
+    polar_decoder_common::initialize_llr_vector(float* llrs, const float* 
input)
+    {
+      volk_32f_s32f_multiply_32f(llrs + block_size() * block_power(), input, 
D_LLR_FACTOR, block_size());
+    }
+
+    float
+    polar_decoder_common::llr_odd(const float la, const float lb) const
+    {
+      return copysignf(1.0f, la) * copysignf(1.0f, lb) * std::min(fabs(la), 
fabs(lb));
+    }
+
+    float
+    polar_decoder_common::llr_even(const float la, const float lb, const 
unsigned char f) const
+    {
+      switch(f){
+        case 0:
+          return lb + la;
+        default:
+          return lb - la;
+      }
+    }
+
+    void
+    polar_decoder_common::butterfly(float* llrs, const int stage, unsigned 
char* u, const int u_num)
+    {
+//      if(!(block_power() > stage)){
+//        return;
+//      }
+      const int next_stage = stage + 1;
+      const int stage_half_block_size = block_size() >> next_stage;
+
+//      // this is a natural bit order impl
+      float* next_llrs = llrs + block_size(); // LLRs are stored in an 
consecutive array.
+      float* call_row_llr = llrs + u_num;
+      const int upper_right = u_num >> 1; // floor divide by 2.
+      const float* upper_right_llr_ptr = next_llrs + upper_right;
+      const float* lower_right_llr_ptr = upper_right_llr_ptr + 
stage_half_block_size;
+
+      if(u_num % 2){
+        const unsigned char f = u[u_num - 1];
+//        const unsigned char f = fetch_bit_at_pos(u, u_num - 1);
+        *call_row_llr = llr_even(*upper_right_llr_ptr, *lower_right_llr_ptr, 
f);
+        return;
+      }
+
+      if(block_power() > next_stage) {
+        unsigned char* u_half = u + block_size();
+        odd_xor_even_values(u_half, u, u_num);
+        butterfly(next_llrs, next_stage, u_half, upper_right);
+
+        even_u_values(u_half, u, u_num);
+        butterfly(next_llrs + stage_half_block_size, next_stage, u_half, 
upper_right);
+      }
+
+      *call_row_llr = llr_odd(*upper_right_llr_ptr, *lower_right_llr_ptr);
+    }
+
+
+    void
+    polar_decoder_common::even_u_values(unsigned char* u_even, const unsigned 
char* u,
+                                             const int u_num)
+    {
+      u++;
+      for(int i = 1; i < u_num; i += 2){
+        *u_even++ = *u;
+        u += 2;
+      }
+
+//      short* target = (short*) u_even;
+//      short* src = (short*) u;
+//
+//      const int iterations = std::max(1, u_num >> 3);
+//      for(int i = 0; i < iterations; i++){
+//        *target = *src << 1;
+//        demortonize_values((unsigned char*) target);
+//        u_even++;
+//        target = (short*) u_even;
+//        src++;
+//      }
+    }
+
+    void
+    polar_decoder_common::odd_xor_even_values(unsigned char* u_xor, const 
unsigned char* u,
+                                                   const int u_num)
+    {
+      for(int i = 1; i < u_num; i += 2){
+        *u_xor++ = *u ^ *(u + 1);
+        u += 2;
+      }
+
+//      short* target = (short*) u_xor;
+//      short* src = (short*) u;
+//
+//      const int iterations = std::max(1, u_num >> 3);
+//      for(int i = 0; i < iterations; i++){
+//        *target = *src ^ (*src << 1);
+//        demortonize_values((unsigned char*) target);
+//        u_xor++;
+//        target = (short*) u_xor;
+//        src++;
+//      }
+    }
+
+    void
+    polar_decoder_common::extract_info_bits(unsigned char* output, const 
unsigned char* input) const
+    {
+      unsigned int frozenbit_num = 0;
+      for(int i = 0; i < block_size(); i++){
+        if(frozenbit_num < d_frozen_bit_positions.size() && 
d_frozen_bit_positions.at(frozenbit_num) == i){
+          frozenbit_num++;
+        }
+        else{
+          *output++ = *input;
+        }
+        input++;
+      }
+
+//      unsigned int frozenbit_num = 0;
+//      for(int i = 0; i < block_size(); i++){
+//        if(frozenbit_num < d_frozen_bit_positions.size() && 
d_frozen_bit_positions.at(frozenbit_num) == i){
+//          frozenbit_num++;
+//        }
+//        else{
+//          *output++ = fetch_bit_at_pos(input, i); // *input;
+//        }
+//      }
+    }
+
+    void
+    polar_decoder_common::demortonize_values(unsigned char* u)
+    {
+      *u &= 0xaa;                   // b0d0f0h0
+      *u = (*u ^ (*u << 1)) & 0xcc; // bd00fh00
+      *u = (*u ^ (*u << 2)) & 0xf0; // bdfh0000
+
+      unsigned char* u2 = u + 1;
+      *u2 &= 0xaa;                   // b0d0f0h0
+      *u2 = (*u2 ^ (*u2 << 1)) & 0xcc; // bd00fh00
+      *u2 = (*u2 ^ (*u2 << 2)) & 0xf0; // bdfh0000
+      *u ^= (*u2 >> 4);
+    }
+
+    void
+    polar_decoder_common::print_pretty_llr_vector(const float* llr_vec) const
+    {
+      for(int row = 0; row < block_size(); row++) {
+        std::cout << row << "->" << int(bit_reverse(row, block_power())) << 
":\t";
+        for(int stage = 0; stage < block_power() + 1; stage++) {
+          printf("%+4.2f, ", llr_vec[(stage * block_size()) + row]);
+        }
+        std::cout << std::endl;
+      }
+    }
+
+  } /* namespace fec */
+} /* namespace gr */
+
diff --git a/gr-fec/lib/polar_decoder_sc.cc b/gr-fec/lib/polar_decoder_sc.cc
new file mode 100644
index 0000000..e4f64b5
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_sc.cc
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include <gnuradio/fec/polar_decoder_sc.h>
+#include <volk/volk.h>
+
+#include <cmath>
+#include <cstdio>
+
+namespace gr
+{
+  namespace fec
+  {
+
+    generic_decoder::sptr
+    polar_decoder_sc::make(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions,
+                           std::vector<char> frozen_bit_values, bool is_packed)
+    {
+      return generic_decoder::sptr(
+          new polar_decoder_sc(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values,
+                               is_packed));
+    }
+
+    polar_decoder_sc::polar_decoder_sc(int block_size, int num_info_bits,
+                                       std::vector<int> frozen_bit_positions,
+                                       std::vector<char> frozen_bit_values, 
bool is_packed) :
+        polar_decoder_common(block_size, num_info_bits, frozen_bit_positions, 
frozen_bit_values, is_packed),
+        d_frozen_bit_counter(0)
+    {
+      d_llr_vec = (float*) volk_malloc(sizeof(float) * block_size * 
(block_power() + 1), volk_get_alignment());
+      memset(d_llr_vec, 0, sizeof(float) * block_size * (block_power() + 1));
+      d_u_hat_vec = (unsigned char*) volk_malloc(block_size * (block_power() + 
1), volk_get_alignment());
+      memset(d_u_hat_vec, 0, sizeof(unsigned char) * block_size * 
(block_power() + 1));
+    }
+
+    polar_decoder_sc::~polar_decoder_sc()
+    {
+      volk_free(d_llr_vec);
+      volk_free(d_u_hat_vec);
+    }
+
+    void
+    polar_decoder_sc::generic_work(void* in_buffer, void* out_buffer)
+    {
+      const float *in = (const float*) in_buffer;
+      unsigned char *out = (unsigned char*) out_buffer;
+
+      initialize_llr_vector(d_llr_vec, in);
+      sc_decode(d_llr_vec, d_u_hat_vec);
+      extract_info_bits(out, d_u_hat_vec);
+    }
+
+    void
+    polar_decoder_sc::sc_decode(float* llrs, unsigned char* u)
+    {
+      d_frozen_bit_counter = 0;
+      memset(u, 0, sizeof(unsigned char) * block_size() * block_power());
+      for(int i = 0; i < block_size(); i++){
+        butterfly(llrs, 0, u, i);
+        u[i] = retrieve_bit_from_llr(llrs[i], i);
+//        const unsigned char bit = retrieve_bit_from_llr(llrs[i], i);
+//        insert_bit_at_pos(u, bit, i);
+      }
+    }
+
+    unsigned char
+    polar_decoder_sc::retrieve_bit_from_llr(float llr, const int pos)
+    {
+      if(d_frozen_bit_counter < d_frozen_bit_positions.size() && pos == 
d_frozen_bit_positions.at(d_frozen_bit_counter)){
+        return d_frozen_bit_values.at(d_frozen_bit_counter++);
+      }
+      return llr_bit_decision(llr);
+    }
+  } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/polar_decoder_sc_list.cc 
b/gr-fec/lib/polar_decoder_sc_list.cc
new file mode 100644
index 0000000..9340e30
--- /dev/null
+++ b/gr-fec/lib/polar_decoder_sc_list.cc
@@ -0,0 +1,123 @@
+/* -*- c++ -*- */
+/* 
+ * Copyright 2015 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/io_signature.h>
+#include <gnuradio/fec/polar_decoder_sc_list.h>
+#include <volk/volk.h>
+#include <scl_list.h>
+
+#include <cmath>
+#include <algorithm>
+
+namespace gr
+{
+  namespace fec
+  {
+
+    generic_decoder::sptr
+    polar_decoder_sc_list::make(int max_list_size, int block_size, int 
num_info_bits,
+                                std::vector<int> frozen_bit_positions,
+                                std::vector<char> frozen_bit_values, bool 
is_packed)
+    {
+      return generic_decoder::sptr(
+          new polar_decoder_sc_list(max_list_size, block_size, num_info_bits, 
frozen_bit_positions,
+                                    frozen_bit_values, is_packed));
+    }
+
+    polar_decoder_sc_list::polar_decoder_sc_list(int max_list_size, int 
block_size,
+                                                 int num_info_bits,
+                                                 std::vector<int> 
frozen_bit_positions,
+                                                 std::vector<char> 
frozen_bit_values,
+                                                 bool is_packed) :
+            polar_decoder_common(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values,
+                                 is_packed), d_max_list_size(max_list_size), 
d_frozen_bit_counter(0)
+    {
+      d_scl = new polar::scl_list(max_list_size, block_size, block_power());
+    }
+
+    polar_decoder_sc_list::~polar_decoder_sc_list()
+    {
+      delete d_scl;
+    }
+
+    void
+    polar_decoder_sc_list::generic_work(void* in_buffer, void* out_buffer)
+    {
+      const float *in = (const float*) in_buffer;
+      unsigned char *out = (unsigned char*) out_buffer;
+      polar::path* init_path = d_scl->initial_path();
+      initialize_llr_vector(init_path->llr_vec, in);
+      memset(init_path->u_vec, 0, sizeof(unsigned char) * block_size() * 
(block_power() + 1));
+      decode_list();
+      const polar::path* temp = d_scl->optimal_path();
+      extract_info_bits(out, temp->u_vec);
+    }
+
+    void
+    polar_decoder_sc_list::decode_list()
+    {
+      d_frozen_bit_counter = 0;
+      for(int i = 0; i < block_size(); i++){
+        calculate_next_llr_in_paths(i);
+      }
+
+    }
+
+    void
+    polar_decoder_sc_list::calculate_next_llr_in_paths(int u_num)
+    {
+      for(unsigned int i = 0; i < d_scl->active_size(); i++){
+        polar::path* current_path = d_scl->next_active_path();
+        calculate_next_llr(current_path, u_num);
+      }
+
+      // 1. if frozen bit, update with known value
+      if(d_frozen_bit_counter < d_frozen_bit_positions.size() && u_num == 
d_frozen_bit_positions.at(d_frozen_bit_counter)){
+        update_with_frozenbit(u_num);
+      }
+      // 2. info bit
+      else{
+        d_scl->set_info_bit(u_num);
+      }
+    }
+
+    void
+    polar_decoder_sc_list::update_with_frozenbit(const int u_num)
+    {
+      unsigned char frozen_bit = d_frozen_bit_values[d_frozen_bit_counter];
+      d_scl->set_frozen_bit(frozen_bit, u_num);
+      d_frozen_bit_counter++;
+    }
+
+    void
+    polar_decoder_sc_list::calculate_next_llr(polar::path* current_path, int 
u_num)
+    {
+      butterfly(current_path->llr_vec, 0, current_path->u_vec, u_num);
+    }
+  } /* namespace fec */
+} /* namespace gr */
+
+
diff --git a/gr-fec/lib/polar_encoder.cc b/gr-fec/lib/polar_encoder.cc
index 1214e80..7187ea6 100644
--- a/gr-fec/lib/polar_encoder.cc
+++ b/gr-fec/lib/polar_encoder.cc
@@ -33,83 +33,63 @@
 #include <gnuradio/blocks/pack_k_bits.h>
 #include <gnuradio/blocks/unpack_k_bits.h>
 
-namespace gr {
-  namespace fec {
+namespace gr
+{
+  namespace fec
+  {
 
     generic_encoder::sptr
     polar_encoder::make(int block_size, int num_info_bits, std::vector<int> 
frozen_bit_positions,
                         std::vector<char> frozen_bit_values, bool is_packed)
     {
-      return generic_encoder::sptr(new polar_encoder(block_size, 
num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed));
+      return generic_encoder::sptr(
+          new polar_encoder(block_size, num_info_bits, frozen_bit_positions, 
frozen_bit_values,
+                            is_packed));
     }
 
-    polar_encoder::polar_encoder(int block_size, int num_info_bits, 
std::vector<int> frozen_bit_positions, std::vector<char> frozen_bit_values, 
bool is_packed):
-        d_block_size(block_size),
-        d_input_size(num_info_bits / (is_packed ? 8 : 1)),
-        d_output_size(block_size / (is_packed ? 8 : 1)),
-        d_is_packed(is_packed),
-        d_num_info_bits(num_info_bits),
-        d_frozen_bit_positions(frozen_bit_positions),
-        d_frozen_bit_values(frozen_bit_values)
+    polar_encoder::polar_encoder(int block_size, int num_info_bits,
+                                 std::vector<int> frozen_bit_positions,
+                                 std::vector<char> frozen_bit_values, bool 
is_packed) :
+        polar_common(block_size, num_info_bits, frozen_bit_positions, 
frozen_bit_values, is_packed),
+            d_frozen_bit_positions(frozen_bit_positions),
+            d_frozen_bit_values(frozen_bit_values)
     {
-      int n = (int) log2(float(block_size));
-      d_block_power = n;
-      if(pow(2, n) != block_size){
-        throw std::runtime_error("block_size MUST be a power of 2!");
-      }
-
-      unsigned int num_frozen_bits = d_block_size - d_num_info_bits;
-      if(num_frozen_bits != d_frozen_bit_positions.size()){
-        throw std::runtime_error("number of frozen bit positions must equal 
block_size - num_info_bits");
-      }
+      unsigned int num_frozen_bits = block_size - num_info_bits;
 
-      while(d_frozen_bit_values.size() < num_frozen_bits){
+      while(d_frozen_bit_values.size() < num_frozen_bits) {
         d_frozen_bit_values.push_back(0);
       }
 
-      int k = 8;
-      d_unpacker = new gr::blocks::kernel::unpack_k_bits(k);
-      d_packer = new gr::blocks::kernel::pack_k_bits(k);
-
       setup_frozen_bit_inserter();
     }
 
     void
     polar_encoder::setup_frozen_bit_inserter()
     {
-      d_block_array = (unsigned char*) volk_malloc(d_block_size >> 3, 
volk_get_alignment());
-      d_frozen_bit_prototype = (unsigned char*) volk_malloc(d_block_size >> 3, 
volk_get_alignment());
-      memset(d_frozen_bit_prototype, 0, d_block_size >> 3);
+      d_block_array = (unsigned char*) volk_malloc(block_size() >> 3, 
volk_get_alignment());
+      d_frozen_bit_prototype = (unsigned char*) volk_malloc(block_size() >> 3,
+                                                            
volk_get_alignment());
+      memset(d_frozen_bit_prototype, 0, block_size() >> 3);
 
-      for(unsigned int i = 0; i < d_frozen_bit_positions.size(); i++){
-        int rev_pos = (int) bit_reverse((long) d_frozen_bit_positions.at(i), 
d_block_power);
+      for(unsigned int i = 0; i < d_frozen_bit_positions.size(); i++) {
+        int rev_pos = (int) bit_reverse((long) d_frozen_bit_positions.at(i), 
block_power());
         unsigned char frozen_bit = (unsigned char) d_frozen_bit_values.at(i);
-        
insert_unpacked_bit_into_packed_array_at_position(d_frozen_bit_prototype, 
frozen_bit, rev_pos);
+        
insert_unpacked_bit_into_packed_array_at_position(d_frozen_bit_prototype, 
frozen_bit,
+                                                          rev_pos);
       }
 
-//      print_packed_bit_array(d_frozen_bit_prototype, d_block_size >> 3);
-
-      int num_frozen_bit = 0;
-      for(int i = 0; i < d_block_size; i++){
-        int frozen_pos = d_frozen_bit_positions.at(num_frozen_bit);
-        if(i != frozen_pos){
-          d_info_bit_positions.push_back((int) bit_reverse((long) i, 
d_block_power));
-        }
-        else{
-          num_frozen_bit++;
-          num_frozen_bit = std::min(num_frozen_bit, (int) 
(d_frozen_bit_positions.size() - 1));
-        }
+      std::vector<int> temp_vec = info_bit_position_vector();
+      for(unsigned int i = 0; i < temp_vec.size(); i++){
+        d_info_bit_positions.push_back((int) bit_reverse((long) 
temp_vec.at(i), block_power()));
       }
-      if((int) d_info_bit_positions.size() != d_num_info_bits){
+
+      if((int) d_info_bit_positions.size() != num_info_bits()) {
         throw std::runtime_error("number of info bit positions MUST equal 
num_info_bits (K)!");
       }
     }
 
     polar_encoder::~polar_encoder()
     {
-      delete d_unpacker;
-      delete d_packer;
-
       volk_free(d_block_array);
       volk_free(d_frozen_bit_prototype);
     }
@@ -120,14 +100,14 @@ namespace gr {
       const unsigned char *in = (const unsigned char*) in_buffer;
       unsigned char *out = (unsigned char*) out_buffer;
 
-      if(d_is_packed){
+      if(is_packed()) {
         insert_packed_frozen_bits_and_reverse(out, in);
         encode_vector_packed(out);
       }
-      else{
+      else {
         insert_unpacked_frozen_bits_and_reverse(d_block_array, in);
         encode_vector_packed(d_block_array);
-        d_unpacker->unpack(out, d_block_array, d_block_size >> 3);
+        unpacker()->unpack(out, d_block_array, block_size() >> 3);
       }
 
 //      insert_frozen_bits(d_block_array, in);
@@ -145,8 +125,8 @@ namespace gr {
     void
     polar_encoder::encode_vector_packed_subbyte(unsigned char* target) const
     {
-      int num_bytes_per_block = d_block_size >> 3;
-      while(num_bytes_per_block){
+      int num_bytes_per_block = block_size() >> 3;
+      while(num_bytes_per_block) {
         encode_packed_byte(target);
         ++target;
         --num_bytes_per_block;
@@ -168,15 +148,15 @@ namespace gr {
     {
       int branch_byte_size = 1;
       unsigned char* pos;
-      int n_branches = d_block_size >> 4;
+      int n_branches = block_size() >> 4;
       int byte = 0;
-      for(int stage = 3; stage < d_block_power; ++stage){
+      for(int stage = 3; stage < block_power(); ++stage) {
         pos = target;
 
-        for(int branch = 0; branch < n_branches; ++branch){
+        for(int branch = 0; branch < n_branches; ++branch) {
 
           byte = 0;
-          while(byte < branch_byte_size){
+          while(byte < branch_byte_size) {
             *pos ^= *(pos + branch_byte_size);
             ++pos;
             ++byte;
@@ -194,12 +174,13 @@ namespace gr {
     polar_encoder::insert_unpacked_frozen_bits_and_reverse(unsigned char* 
target,
                                                            const unsigned 
char* input) const
     {
-      memcpy(target, d_frozen_bit_prototype, d_block_size >> 3);
+      memcpy(target, d_frozen_bit_prototype, block_size() >> 3);
       const int* info_bit_positions_ptr = &d_info_bit_positions[0];
-      const unsigned char* end_input = input + d_num_info_bits;
+      const unsigned char* end_input = input + num_info_bits();
       int bit_pos = 7;
-      while(input < end_input){
-        insert_packet_bit_into_packed_array_at_position(target, *input++, 
*info_bit_positions_ptr++, bit_pos);
+      while(input < end_input) {
+        insert_packet_bit_into_packed_array_at_position(target, *input++, 
*info_bit_positions_ptr++,
+                                                        bit_pos);
       }
     }
 
@@ -207,16 +188,16 @@ namespace gr {
     polar_encoder::insert_packed_frozen_bits_and_reverse(unsigned char* target,
                                                          const unsigned char* 
input) const
     {
-      memcpy(target, d_frozen_bit_prototype, d_block_size >> 3);
+      memcpy(target, d_frozen_bit_prototype, block_size() >> 3);
       const int* info_bit_positions_ptr = &d_info_bit_positions[0];
       int bit_num = 0;
       unsigned char byte = *input;
       int bit_pos;
-      while(bit_num < d_num_info_bits){
+      while(bit_num < num_info_bits()) {
         bit_pos = *info_bit_positions_ptr++;
         insert_packet_bit_into_packed_array_at_position(target, byte, bit_pos, 
bit_num % 8);
         ++bit_num;
-        if(bit_num % 8 == 0){
+        if(bit_num % 8 == 0) {
           ++input;
           byte = *input;
         }
@@ -239,38 +220,22 @@ namespace gr {
                                                                    const int 
target_pos,
                                                                    const int 
bit_pos) const
     {
-      insert_unpacked_bit_into_packed_array_at_position(target, (bit >> (7 - 
bit_pos)) & 0x01, target_pos);
-    }
-
-    void
-    polar_encoder::print_packed_bit_array(const unsigned char* printed_array, 
const int num_bytes) const
-    {
-      int num_bits = num_bytes << 3;
-      unsigned char* temp = (unsigned char*) volk_malloc(num_bits, 
volk_get_alignment());
-      d_unpacker->unpack(temp, printed_array, num_bytes);
-
-
-      std::cout << "[";
-      for(int i = 0; i < num_bits; i++){
-        std::cout << (int) *(temp + i) << " ";
-      }
-      std::cout << "]" << std::endl;
-
-      volk_free(temp);
+      insert_unpacked_bit_into_packed_array_at_position(target, (bit >> (7 - 
bit_pos)) & 0x01,
+                                                        target_pos);
     }
 
     void
     polar_encoder::insert_frozen_bits(unsigned char* target, const unsigned 
char* input)
     {
       int frozen_num = 0;
-      int num_frozen_bits = d_block_size - d_num_info_bits;
+      int num_frozen_bits = block_size() - num_info_bits();
       int info_num = 0;
-      for(int i = 0; i < d_block_size; i++){
-        if(frozen_num < num_frozen_bits && 
d_frozen_bit_positions.at(frozen_num) == i){
+      for(int i = 0; i < block_size(); i++) {
+        if(frozen_num < num_frozen_bits && 
d_frozen_bit_positions.at(frozen_num) == i) {
           target[i] = d_frozen_bit_values.at(frozen_num);
           frozen_num++;
         }
-        else{
+        else {
           target[i] = input[info_num];
           info_num++;
         }
@@ -280,19 +245,19 @@ namespace gr {
     void
     polar_encoder::bit_reverse_vector(unsigned char* target, const unsigned 
char* input)
     {
-      for(int i = 0; i < d_block_size; i++){
-        target[bit_reverse(long(i), d_block_power)] = input[i];
+      for(int i = 0; i < block_size(); i++) {
+        target[bit_reverse(long(i), block_power())] = input[i];
       }
     }
 
     void
     polar_encoder::encode_vector(unsigned char* target)
     {
-      for(int stage = 0; stage < d_block_power; stage++){
+      for(int stage = 0; stage < block_power(); stage++) {
         int n_branches = pow(2, stage);
-        int branch_elements = d_block_size / (2 * n_branches);
-        for(int branch = 0; branch < n_branches; branch++){
-          for(int e = 0; e < branch_elements; e++){
+        int branch_elements = block_size() / (2 * n_branches);
+        for(int branch = 0; branch < n_branches; branch++) {
+          for(int e = 0; e < branch_elements; e++) {
             int pos = branch * branch_elements * 2 + e;
             target[pos] ^= target[pos + branch_elements];
           }
@@ -300,19 +265,6 @@ namespace gr {
       }
     }
 
-    long
-    polar_encoder::bit_reverse(long value, int active_bits) const
-    {
-      long r = 0;
-      for(int i = 0; i < active_bits; i++){
-        r <<= 1;
-        r |= value & 1;
-        value >>= 1;
-      }
-      return r;
-    }
-
   } /* namespace fec */
 } /* namespace gr */
 
-
diff --git a/gr-fec/lib/scl_list.cc b/gr-fec/lib/scl_list.cc
new file mode 100644
index 0000000..6942bfb
--- /dev/null
+++ b/gr-fec/lib/scl_list.cc
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <scl_list.h>
+#include <cstring>
+#include <iostream>
+#include <algorithm>
+#include <volk/volk.h>
+
+namespace gr {
+  namespace fec {
+    namespace polar {
+
+      scl_list::scl_list(const unsigned int size, const unsigned int 
block_size, const unsigned int block_power):
+          d_list_size(size), d_block_size(block_size), 
d_block_power(block_power), d_num_buff_elements(block_size * (block_power + 1))
+      {
+        for(unsigned int i = 0; i < 2 * size; i++){
+          d_path_list.push_back(new path());
+        }
+
+        for(unsigned int i = 0; i < size; i++){
+          d_path_list[i]->llr_vec = (float*) volk_malloc(sizeof(float) * 
d_num_buff_elements, volk_get_alignment());
+          memset(d_path_list[i]->llr_vec, 0, sizeof(float) * 
d_num_buff_elements);
+          d_path_list[i]->u_vec = (unsigned char*) volk_malloc(sizeof(unsigned 
char) * d_num_buff_elements, volk_get_alignment());
+          memset(d_path_list[i]->u_vec, 0, sizeof(unsigned char) * 
d_num_buff_elements);
+          d_path_list[i]->owns_vectors = true;
+        }
+
+        d_path_list[0]->is_active = true;
+        d_active_path_counter = 1;
+        d_active_pos = 0;
+      }
+
+      scl_list::~scl_list()
+      {
+        for(unsigned int i = 0; i < d_path_list.size(); i++){
+          delete d_path_list[i];
+        }
+      }
+
+
+      const path*
+      scl_list::optimal_path()
+      {
+        const path* temp = *std::min_element(d_path_list.begin(), 
d_path_list.begin() + d_active_path_counter, path_compare);
+        reset();
+        return temp;
+      }
+
+      void
+      scl_list::reset()
+      {
+        // leave 0th element active for next iteration
+        d_path_list[0]->path_metric = 0.0f;
+        for(unsigned int i = 1; i < d_path_list.size(); i++){
+          d_path_list[i]->is_active = false;
+          d_path_list[i]->path_metric = 0.0f;
+        }
+        d_active_path_counter = 1;
+        d_active_pos = 0;
+      }
+
+      void
+      scl_list::set_info_bit(const int bit_pos)
+      {
+        if(d_active_path_counter < d_list_size) {
+          const int offset = d_active_path_counter;
+          for(int i = 0; i < offset; i++) {
+            duplicate_path(d_path_list[i + offset], d_path_list[i]);
+            d_path_list[i]->path_metric = 
update_path_metric(d_path_list[i]->path_metric,
+                                                             
d_path_list[i]->llr_vec[bit_pos], 0);
+            d_path_list[i + offset]->path_metric = update_path_metric(
+                d_path_list[i + offset]->path_metric, d_path_list[i + 
offset]->llr_vec[bit_pos], 1);
+            d_path_list[i]->u_vec[bit_pos] = 0;
+//            insert_bit_at_pos(d_path_list[i]->u_vec, 0, bit_pos);
+            d_path_list[i + offset]->u_vec[bit_pos] = 1;
+//            insert_bit_at_pos(d_path_list[i + offset]->u_vec, 1, bit_pos);
+          }
+        }
+        else {
+
+          for(unsigned int i = 0; i < d_list_size; i++) {
+            branch_paths(d_path_list[i + d_list_size], d_path_list[i], 
d_path_list[i]->llr_vec[bit_pos]);
+          }
+          std::sort(d_path_list.begin(), d_path_list.end(), path_compare);
+
+          for(unsigned int i = 0; i < d_list_size; i++) {
+            if(!d_path_list[i]->owns_vectors) {
+              int t_pos = d_list_size;
+              while(!d_path_list[t_pos]->owns_vectors) {
+                t_pos++;
+              }
+              steal_vector_ownership(d_path_list[i], d_path_list[t_pos]);
+              d_path_list[i]->u_vec[bit_pos] = 1;
+//              insert_bit_at_pos(d_path_list[i]->u_vec, 1, bit_pos);
+            }
+            else{
+              d_path_list[i]->u_vec[bit_pos] = 0;
+//              insert_bit_at_pos(d_path_list[i]->u_vec, 0, bit_pos);
+            }
+          }
+        }
+        d_active_pos = 0;
+      }
+
+      void
+      scl_list::branch_paths(path* target, path* original, const float llr)
+      {
+        target->path_metric = update_path_metric(original->path_metric, llr, 
1);
+        original->path_metric = update_path_metric(original->path_metric, llr, 
0);
+        target->llr_vec = original->llr_vec;
+        target->u_vec = original->u_vec;
+      }
+
+      void
+      scl_list::steal_vector_ownership(path* target, path* original)
+      {
+        memcpy(original->llr_vec, target->llr_vec, sizeof(float) * 
d_num_buff_elements);
+        memcpy(original->u_vec, target->u_vec, sizeof(unsigned char) * 
d_num_buff_elements);
+        target->llr_vec = original->llr_vec;
+        target->u_vec = original->u_vec;
+        target->owns_vectors = true;
+        original->owns_vectors = false;
+      }
+
+      void
+      scl_list::duplicate_path(path* target, const path* original)
+      {
+        memcpy(target->llr_vec, original->llr_vec, sizeof(float) * 
d_num_buff_elements);
+        memcpy(target->u_vec, original->u_vec, sizeof(unsigned char) * 
d_num_buff_elements);
+        target->path_metric = original->path_metric;
+        d_active_path_counter++;
+        target->is_active = true;
+      }
+
+      float
+      scl_list::update_path_metric(const float last_pm, const float llr,
+                                                   const float ui) const
+      {
+        if((ui == 0 && llr > 0.0f) || (ui == 1 && llr < 0.0f)){
+//        if(ui == (unsigned char) (0.5 * 1 - copysignf(1.0f, llr))){
+          return last_pm;
+        }
+        return last_pm + fabs(llr);
+      }
+
+      void
+      scl_list::set_frozen_bit(const unsigned char frozen_bit, const int 
bit_pos)
+      {
+        for(unsigned int i = 0; i < d_active_path_counter; i++){
+//          insert_bit_at_pos(d_path_list[i]->u_vec, frozen_bit, bit_pos);
+          d_path_list[i]->u_vec[bit_pos] = frozen_bit;
+          d_path_list[i]->path_metric = 
update_path_metric(d_path_list[i]->path_metric, 
d_path_list[i]->llr_vec[bit_pos], frozen_bit);
+        }
+        d_active_pos = 0;
+      }
+
+      path::path():
+        path_metric(0.0f), owns_vectors(false), is_active(false), 
llr_vec(NULL), u_vec(NULL)
+      {
+      }
+
+      path::~path(){
+        if(owns_vectors){
+          volk_free(llr_vec);
+          volk_free(u_vec);
+        }
+      }
+
+    } /* namespace polar */
+  } /* namespace fec */
+} /* namespace gr */
diff --git a/gr-fec/lib/scl_list.h b/gr-fec/lib/scl_list.h
new file mode 100644
index 0000000..8f09198
--- /dev/null
+++ b/gr-fec/lib/scl_list.h
@@ -0,0 +1,83 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2015 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_FEC_SCL_LIST_H
+#define INCLUDED_FEC_SCL_LIST_H
+
+#include <vector>
+
+namespace gr {
+  namespace fec {
+    namespace polar {
+      struct path {
+        path();
+        ~path();
+        float path_metric;
+        bool owns_vectors;
+        bool is_active;
+        float* llr_vec;
+        unsigned char* u_vec;
+      };
+
+      /*!
+       * \brief List implementation for Successive Cancellation List decoders
+       *
+       */
+      class scl_list{
+        const unsigned int d_list_size;
+        const unsigned int d_block_size;
+        const unsigned int d_block_power;
+        const unsigned int d_num_buff_elements;
+        std::vector<path*> d_path_list;
+        unsigned int d_active_path_counter;
+        unsigned int d_active_pos;
+
+        float update_path_metric(const float last_pm, const float llr, const 
float ui) const;
+        void duplicate_path(path* target, const path* original);
+        void branch_paths(path* target, path* original, const float llr);
+        void steal_vector_ownership(path* target, path* original);
+
+        static void insert_bit_at_pos(unsigned char* u, const unsigned char 
ui, const unsigned int pos){u[pos >> 3] ^= ui << (7 - (pos % 8));};
+
+        // comparator for std::sort
+        static bool path_compare(path* first, path* second){return 
first->path_metric < second->path_metric;};
+
+      public:
+        scl_list(const unsigned int list_size, const unsigned int block_size, 
const unsigned int block_power);
+        virtual
+        ~scl_list();
+        const unsigned int size() const {return d_list_size;};
+        const unsigned int active_size() const {return d_active_path_counter;};
+
+        path* initial_path() const {return d_path_list[0];};
+        path* next_active_path(){return d_path_list[d_active_pos++];};
+        void set_frozen_bit(const unsigned char frozen_bit, const int bit_pos);
+        void set_info_bit(const int bit_pos);
+        const path* optimal_path();
+        void reset();
+      };
+
+    } /* namespace polar */
+  } /* namespace fec */
+} /* namespace gr */
+
+#endif /* INCLUDED_FEC_SCL_LIST_H */
diff --git a/gr-fec/python/fec/polar/channel_construction_bec.py 
b/gr-fec/python/fec/polar/channel_construction_bec.py
index cd61f46..4d3654d 100644
--- a/gr-fec/python/fec/polar/channel_construction_bec.py
+++ b/gr-fec/python/fec/polar/channel_construction_bec.py
@@ -87,6 +87,12 @@ def get_frozen_bit_indices_from_capacities(chan_caps, 
nfrozen):
     return np.sort(indexes)
 
 
+def get_bec_frozen_indices(nblock, kfrozen, eta):
+    bec_caps = calculate_bec_channel_capacities(eta, nblock)
+    positions = get_frozen_bit_indices_from_capacities(bec_caps, kfrozen)
+    return positions
+
+
 def bec_channel_contruction_tests():
     n = 2 ** 10
     k = n // 2
diff --git a/gr-fec/python/fec/polar/channel_construction_bsc.py 
b/gr-fec/python/fec/polar/channel_construction_bsc.py
index 8cee7ce..2263bf0 100755
--- a/gr-fec/python/fec/polar/channel_construction_bsc.py
+++ b/gr-fec/python/fec/polar/channel_construction_bsc.py
@@ -23,23 +23,6 @@ from helper_functions import *
 import matplotlib.pyplot as plt
 
 
-# def bit_reverse(value, n):
-#     # is this really missing in NumPy???
-#     bits = np.zeros(n, type(value))
-#     for index in range(n):
-#         mask = 1
-#         mask = np.left_shift(mask, index)
-#         bit = np.bitwise_and(value, mask)
-#         bit = np.right_shift(bit, index)
-#         bits[index] = bit
-#     bits = bits[::-1]
-#     result = 0
-#     for index, bit in enumerate(bits):
-#         bit = np.left_shift(bit, index)
-#         result += bit
-#     return result
-
-
 def get_Bn(n):
     # this is a bit reversal matrix.
     lw = int(np.log2(n))  # number of used bits
diff --git a/gr-fec/python/fec/polar/decoder.py 
b/gr-fec/python/fec/polar/decoder.py
index d74f1f9..ef7d700 100644
--- a/gr-fec/python/fec/polar/decoder.py
+++ b/gr-fec/python/fec/polar/decoder.py
@@ -122,16 +122,27 @@ class PolarDecoder(PolarCommon):
             u = np.append(u, ui)
         return u
 
+    def _llr_retrieve_bit(self, llr, pos):
+        f_index = np.where(self.frozen_bit_position == pos)[0]
+        if not f_index.size == 0:
+            ui = self.frozenbits[f_index][0]
+        else:
+            ui = self._llr_bit_decision(llr)
+        return ui
+
     def _butterfly_decode_bits(self, pos, graph, u):
+        bit_num = u.size
         llr = graph[pos][0]
-        ui = self._llr_bit_decision(llr)
+        ui = self._llr_retrieve_bit(llr, bit_num)
+        # ui = self._llr_bit_decision(llr)
         u = np.append(u, ui)
         lower_right = pos + (self.N // 2)
         la = graph[pos][1]
         lb = graph[lower_right][1]
         graph[lower_right][0] = self._llr_even(la, lb, ui)
         llr = graph[lower_right][0]
-        ui = self._llr_bit_decision(llr)
+        # ui = self._llr_bit_decision(llr)
+        ui = self._llr_retrieve_bit(llr, u.size)
         u = np.append(u, ui)
         return graph, u
 
diff --git a/gr-fec/python/fec/polar/helper_functions.py 
b/gr-fec/python/fec/polar/helper_functions.py
index ffa4fc1..213f3cb 100644
--- a/gr-fec/python/fec/polar/helper_functions.py
+++ b/gr-fec/python/fec/polar/helper_functions.py
@@ -19,6 +19,7 @@
 #
 
 import numpy as np
+from channel_construction_bec import get_bec_frozen_indices
 
 
 def is_power_of_two(num):
@@ -72,7 +73,8 @@ def pack_byte(bits):
 
 def get_frozen_bit_positions(directory, n, k, p):
     import glob, os
-    os.chdir(directory)
+    if not os.getcwd().endswith(directory):
+        os.chdir(directory)
     prefix = 'frozen_bit_positions_'
     prefix_len = len(prefix)
     for file in glob.glob("*.npy"):
@@ -90,7 +92,7 @@ def get_frozen_bit_positions(directory, n, k, p):
         pstr = float(pstr[0][1:])
         if n == nstr and k == kstr:
             return np.load(filename)
-    return np.arange(k)
+    return get_bec_frozen_indices(n, k, p)
 
 
 def main():
diff --git a/gr-fec/python/fec/polar/testbed.py 
b/gr-fec/python/fec/polar/testbed.py
index 4ace91e..bdf9ae4 100755
--- a/gr-fec/python/fec/polar/testbed.py
+++ b/gr-fec/python/fec/polar/testbed.py
@@ -67,6 +67,24 @@ def approx_value(la, lb):
     return np.sign(la) * np.sign(lb) * np.minimum(np.abs(la), np.abs(lb))
 
 
+def path_metric_exact(last_pm, llr, ui):
+    return last_pm + np.log(1 + np.exp(-1. * llr * (1 - 2 * ui)))
+
+
+def path_metric_approx(last_pm, llr, ui):
+    if ui == int(.5 * (1 - np.sign(llr))):
+        return last_pm
+    return last_pm + np.abs(llr)
+
+
+def calculate_path_metric_vector(metric, llrs, us):
+    res = np.zeros(llrs.size)
+    res[0] = metric(0, llrs[0], us[0])
+    for i in range(1, llrs.size):
+        res[i] = metric(res[i - 1], llrs[i], us[i])
+    return res
+
+
 def test_1024_rate_1_code():
     # effectively a Monte-Carlo simulation for channel polarization.
     ntests = 10000
@@ -135,11 +153,12 @@ def main():
     # frozenbitposition = np.array((0, 1, 2, 3, 4, 5, 8, 9), dtype=int)
     # print frozenbitposition
 
-    test_enc_dec_chain()
+    # test_enc_dec_chain()
 
     # test_1024_rate_1_code()
 
-    # channel_analysis()
+    channel_analysis()
+
 
 if __name__ == '__main__':
     main()
\ No newline at end of file
diff --git a/gr-fec/python/fec/qa_polar_decoder_sc.py 
b/gr-fec/python/fec/qa_polar_decoder_sc.py
new file mode 100644
index 0000000..f26bf9a
--- /dev/null
+++ b/gr-fec/python/fec/qa_polar_decoder_sc.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+from Crypto.Cipher._AES import block_size
+
+from gnuradio import gr, gr_unittest, blocks
+import fec_swig as fec
+from _qa_helper import _qa_helper
+import numpy as np
+import os
+
+from extended_encoder import extended_encoder
+from extended_decoder import extended_decoder
+from polar.encoder import PolarEncoder
+from polar.decoder import PolarDecoder
+from polar.helper_functions import get_frozen_bit_positions
+# from polar.helper_functions import bit_reverse_vector
+
+# print('PID:', os.getpid())
+# raw_input('tell me smth')
+
+class test_polar_decoder_sc(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001_setup(self):
+        is_packed = False
+        block_size = 16
+        num_info_bits = 8
+        frozen_bit_positions = np.arange(block_size - num_info_bits)
+        frozen_bit_values = np.array([],)
+
+        polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+
+        self.assertEqual(num_info_bits, polar_decoder.get_output_size())
+        self.assertEqual(block_size, polar_decoder.get_input_size())
+        self.assertFloatTuplesAlmostEqual((float(block_size) / num_info_bits, 
), (polar_decoder.rate(), ))
+        self.assertFalse(polar_decoder.set_frame_size(10))
+
+    def test_002_one_vector(self):
+        print "test_002_one_vector"
+        is_packed = False
+        block_power = 8
+        block_size = 2 ** block_power
+        num_info_bits = 2 ** (block_power - 1)
+        num_frozen_bits = block_size - num_info_bits
+        frozen_bit_positions = get_frozen_bit_positions('polar', block_size, 
num_frozen_bits, 0.11)
+        frozen_bit_values = np.array([0] * num_frozen_bits,)
+        print frozen_bit_positions
+
+        python_decoder = PolarDecoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+
+        bits = np.ones(num_info_bits, dtype=int)
+        # bits = np.random.randint(2, size=num_info_bits)
+        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+        data = encoder.encode(bits)
+        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+        gr_data = -2.0 * data + 1.0
+
+        polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+        src = blocks.vector_source_f(gr_data, False)
+        dec_block = extended_decoder(polar_decoder, None)
+        snk = blocks.vector_sink_b(1)
+
+        self.tb.connect(src, dec_block)
+        self.tb.connect(dec_block, snk)
+        self.tb.run()
+
+        res = np.array(snk.data()).astype(dtype=int)
+
+        ref = python_decoder.decode(data)
+
+        print("input:", data)
+        print("res  :", res)
+        print("ref  :", ref)
+
+        self.assertTupleEqual(tuple(res), tuple(ref))
+
+    def test_003_stream(self):
+        print "test_002_stream"
+        nframes = 3
+        is_packed = False
+        block_power = 8
+        block_size = 2 ** block_power
+        num_info_bits = 2 ** (block_power - 1)
+        num_frozen_bits = block_size - num_info_bits
+        frozen_bit_positions = get_frozen_bit_positions('polar', block_size, 
num_frozen_bits, 0.11)
+        frozen_bit_values = np.array([0] * num_frozen_bits,)
+        print frozen_bit_positions
+
+        python_decoder = PolarDecoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+
+        bits = np.array([], dtype=int)
+        data = np.array([], dtype=int)
+        for n in range(nframes):
+            b = np.random.randint(2, size=num_info_bits)
+            d = encoder.encode(b)
+            bits = np.append(bits, b)
+            data = np.append(data, d)
+        # bits = np.ones(num_info_bits, dtype=int)
+        # bits = np.random.randint(2, size=num_info_bits)
+        # data = encoder.encode(bits)
+        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+        gr_data = -2.0 * data + 1.0
+
+        polar_decoder = fec.polar_decoder_sc.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
+        src = blocks.vector_source_f(gr_data, False)
+        dec_block = extended_decoder(polar_decoder, None)
+        snk = blocks.vector_sink_b(1)
+
+        self.tb.connect(src, dec_block)
+        self.tb.connect(dec_block, snk)
+        self.tb.run()
+
+        res = np.array(snk.data()).astype(dtype=int)
+
+        # ref = python_decoder.decode(data)
+
+        print("input:", data)
+        print("res  :", res)
+        # print("ref  :", ref)
+
+        self.assertTupleEqual(tuple(res), tuple(bits))
+
+
+if __name__ == '__main__':
+    gr_unittest.run(test_polar_decoder_sc)
+
+
diff --git a/gr-fec/python/fec/qa_polar_decoder_sc_list.py 
b/gr-fec/python/fec/qa_polar_decoder_sc_list.py
new file mode 100644
index 0000000..f698a4e
--- /dev/null
+++ b/gr-fec/python/fec/qa_polar_decoder_sc_list.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 Free Software Foundation, Inc.
+#
+# This file is part of GNU Radio
+#
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+#
+
+from gnuradio import gr, gr_unittest, blocks
+import fec_swig as fec
+import numpy as np
+import os
+
+from extended_encoder import extended_encoder
+from extended_decoder import extended_decoder
+from polar.encoder import PolarEncoder
+from polar.decoder import PolarDecoder
+from polar.helper_functions import get_frozen_bit_positions
+# from polar.helper_functions import bit_reverse_vector
+#
+# print('PID:', os.getpid())
+# raw_input('tell me smth')
+
+class test_polar_decoder_sc_list(gr_unittest.TestCase):
+
+    def setUp(self):
+        self.tb = gr.top_block()
+
+    def tearDown(self):
+        self.tb = None
+
+    def test_001_setup(self):
+        is_packed = False
+        block_size = 16
+        num_info_bits = 8
+        max_list_size = 4
+        frozen_bit_positions = np.arange(block_size - num_info_bits)
+        frozen_bit_values = np.array([],)
+
+        polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, 
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+
+        self.assertEqual(num_info_bits, polar_decoder.get_output_size())
+        self.assertEqual(block_size, polar_decoder.get_input_size())
+        self.assertFloatTuplesAlmostEqual((float(block_size) / num_info_bits, 
), (polar_decoder.rate(), ))
+        self.assertFalse(polar_decoder.set_frame_size(10))
+
+    def test_002_one_vector(self):
+        print "test_002_one_vector"
+        is_packed = False
+        expo = 6
+        block_size = 2 ** expo
+        num_info_bits = 2 ** (expo - 1)
+        max_list_size = 2 ** (expo - 2)
+        num_frozen_bits = block_size - num_info_bits
+        frozen_bit_positions = get_frozen_bit_positions('polar', block_size, 
num_frozen_bits, 0.11)
+        frozen_bit_values = np.array([0] * num_frozen_bits,)
+        print(frozen_bit_positions)
+
+        python_decoder = PolarDecoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+
+        # data = np.ones(block_size, dtype=int)
+        bits = np.random.randint(2, size=num_info_bits)
+        # bits = np.ones(num_info_bits, dtype=int)
+        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+        data = encoder.encode(bits)
+        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+        gr_data = -2.0 * data + 1.0
+
+        polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, 
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+        src = blocks.vector_source_f(gr_data, False)
+        dec_block = extended_decoder(polar_decoder, None)
+        snk = blocks.vector_sink_b(1)
+
+        self.tb.connect(src, dec_block)
+        self.tb.connect(dec_block, snk)
+        self.tb.run()
+
+        res = np.array(snk.data()).astype(dtype=int)
+
+        ref = python_decoder.decode(data)
+
+        print("input:", data)
+        print("res  :", res)
+        print("ref  :", ref)
+        print("bits :", bits)
+
+        self.assertTupleEqual(tuple(res), tuple(ref))
+
+    def test_003_stream(self):
+        print "test_003_stream"
+        nframes = 5
+        is_packed = False
+        expo = 8
+        block_size = 2 ** expo
+        num_info_bits = 2 ** (expo - 1)
+        max_list_size = 2 ** (expo - 2)
+        num_frozen_bits = block_size - num_info_bits
+        frozen_bit_positions = get_frozen_bit_positions('polar', block_size, 
num_frozen_bits, 0.11)
+        frozen_bit_values = np.array([0] * num_frozen_bits,)
+        print(frozen_bit_positions)
+
+        encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
+
+        # data = np.ones(block_size, dtype=int)
+        ref = np.array([], dtype=int)
+        data = np.array([], dtype=int)
+        for i in range(nframes):
+            b = np.random.randint(2, size=num_info_bits)
+            d = encoder.encode(b)
+            data = np.append(data, d)
+            ref = np.append(ref, b)
+
+        # bits = np.ones(num_info_bits, dtype=int)
+        # data = encoder.encode(bits)
+        # data = np.array([0, 1, 1, 0, 1, 0, 1, 0], dtype=int)
+        gr_data = -2.0 * data + 1.0
+
+        polar_decoder = fec.polar_decoder_sc_list.make(max_list_size, 
block_size, num_info_bits, frozen_bit_positions, frozen_bit_values, is_packed)
+        src = blocks.vector_source_f(gr_data, False)
+        dec_block = extended_decoder(polar_decoder, None)
+        snk = blocks.vector_sink_b(1)
+
+        self.tb.connect(src, dec_block)
+        self.tb.connect(dec_block, snk)
+        self.tb.run()
+
+        res = np.array(snk.data()).astype(dtype=int)
+
+
+        print("input:", data)
+        print("res  :", res)
+        print("ref  :", ref)
+
+        self.assertTupleEqual(tuple(res), tuple(ref))
+
+
+
+
+if __name__ == '__main__':
+    gr_unittest.run(test_polar_decoder_sc_list)
+
+
+
diff --git a/gr-fec/python/fec/qa_polar_encoder.py 
b/gr-fec/python/fec/qa_polar_encoder.py
index 0362935..4af193e 100644
--- a/gr-fec/python/fec/qa_polar_encoder.py
+++ b/gr-fec/python/fec/qa_polar_encoder.py
@@ -22,14 +22,11 @@
 
 from gnuradio import gr, gr_unittest, blocks
 import fec_swig as fec
-from _qa_helper import _qa_helper
 import numpy as np
 
 from extended_encoder import extended_encoder
-from extended_decoder import extended_decoder
 from polar.encoder import PolarEncoder
 from polar.helper_functions import get_frozen_bit_positions
-from polar.helper_functions import bit_reverse_vector
 
 
 class test_polar_encoder(gr_unittest.TestCase):
@@ -61,21 +58,17 @@ class test_polar_encoder(gr_unittest.TestCase):
         frozen_bit_values = np.array([0] * num_frozen_bits,)
         python_encoder = PolarEncoder(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values)
 
-        is_packed = False
+        is_packed = True
         polar_encoder = fec.polar_encoder.make(block_size, num_info_bits, 
frozen_bit_positions, frozen_bit_values, is_packed)
 
         data = np.ones(num_info_bits, dtype=int)
         src = blocks.vector_source_b(data, False)
-        packer = blocks.pack_k_bits_bb(8)
         enc_block = extended_encoder(polar_encoder, None, '11')
-        unpacker = blocks.unpack_k_bits_bb(8)
         snk = blocks.vector_sink_b(1)
 
-        if is_packed:
-            self.tb.connect(src, packer, enc_block, unpacker, snk)
-        else:
-            self.tb.connect(src, enc_block, snk)
+        self.tb.connect(src, enc_block, snk)
         self.tb.run()
+        print(self.tb.edge_list())
 
         res = np.array(snk.data()).astype(dtype=int)
         penc = python_encoder.encode(data)
@@ -85,7 +78,7 @@ class test_polar_encoder(gr_unittest.TestCase):
         self.assertTupleEqual(tuple(res), tuple(penc))
 
     def test_003_big_input(self):
-        is_packed = False
+        is_packed = True
         num_blocks = 30
         block_size = 256
         num_info_bits = 128
@@ -106,19 +99,13 @@ class test_polar_encoder(gr_unittest.TestCase):
 
 
         src = blocks.vector_source_b(data, False)
-        packer = blocks.pack_k_bits_bb(8)
         enc_block = extended_encoder(polar_encoder, None, '11')
-        unpacker = blocks.unpack_k_bits_bb(8)
         snk = blocks.vector_sink_b(1)
 
-        if is_packed:
-            self.tb.connect(src, packer, enc_block, unpacker, snk)
-        else:
-            self.tb.connect(src, enc_block, snk)
+        self.tb.connect(src, enc_block, snk)
         self.tb.run()
 
         res = np.array(snk.data()).astype(dtype=int)
-        # penc = python_encoder.encode(data)
 
         print(res)
         print(ref)
diff --git a/gr-fec/swig/fec_swig.i b/gr-fec/swig/fec_swig.i
index b5735aa..a33e8d1 100644
--- a/gr-fec/swig/fec_swig.i
+++ b/gr-fec/swig/fec_swig.i
@@ -63,6 +63,10 @@
 #include "gnuradio/fec/tpc_encoder.h"
 #include "gnuradio/fec/tpc_decoder.h"
 #include "gnuradio/fec/polar_encoder.h"
+#include "gnuradio/fec/polar_decoder_sc.h"
+#include "gnuradio/fec/polar_common.h"
+#include "gnuradio/fec/polar_decoder_sc_list.h"
+#include "gnuradio/fec/polar_decoder_common.h"
 %}
 
 %include "gnuradio/fec/generic_decoder.h"
@@ -106,3 +110,7 @@ GR_SWIG_BLOCK_MAGIC2(fec, puncture_bb);
 GR_SWIG_BLOCK_MAGIC2(fec, puncture_ff);
 GR_SWIG_BLOCK_MAGIC2(fec, depuncture_bb);
 %include "gnuradio/fec/polar_encoder.h"
+%include "gnuradio/fec/polar_decoder_sc.h"
+%include "gnuradio/fec/polar_common.h"
+%include "gnuradio/fec/polar_decoder_sc_list.h"
+%include "gnuradio/fec/polar_decoder_common.h"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]