diff --git a/ariths_gen/core/arithmetic_circuits/general_circuit.py b/ariths_gen/core/arithmetic_circuits/general_circuit.py
index c4fb720..6cd6c79 100644
--- a/ariths_gen/core/arithmetic_circuits/general_circuit.py
+++ b/ariths_gen/core/arithmetic_circuits/general_circuit.py
@@ -68,7 +68,7 @@ class GeneralCircuit():
             component: Subcomponent to be added into list of components composing described circuit.
         """
         prefixes = [c.prefix for c in self.components]
-        #assert component.prefix not in prefixes, f"Component with prefix {component.prefix} already exists in the circuit."
+        assert component.prefix not in prefixes, f"Component with prefix {component.prefix} already exists in the circuit."
         self.components.append(component)
         return component
 
@@ -212,28 +212,16 @@ class GeneralCircuit():
         """
         self.circuit_wires = []
         circuit_wires_names = []
-        if isinstance(self.a, Bus):
-            [self.circuit_wires.append(
-                (w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.a.bus]
-            [self.circuit_wires.append(
-                (w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.b.bus]
-            [circuit_wires_names.append(w.name) for w in self.a.bus]
-            [circuit_wires_names.append(w.name) for w in self.b.bus]
-            if hasattr(self, 'c'):
+
+        for input in self.inputs:
+            if isinstance(input, Bus):
                 [self.circuit_wires.append(
-                    (w, f"{w.name}", self.save_wire_id(wire=w))) for w in self.c.bus]
-                [circuit_wires_names.append(w.name) for w in self.c.bus]
-        else:
-            self.circuit_wires.append(
-                (self.a, f"{self.a.name}", self.save_wire_id(wire=self.a)))
-            self.circuit_wires.append(
-                (self.b, f"{self.b.name}", self.save_wire_id(wire=self.b)))
-            circuit_wires_names.append(self.a.name)
-            circuit_wires_names.append(self.b.name)
-            if hasattr(self, 'c'):
+                    (w, f"{w.name}", self.save_wire_id(wire=w))) for w in input.bus]
+                [circuit_wires_names.append(w.name) for w in input.bus]
+            else:
                 self.circuit_wires.append(
-                    (self.c, f"{self.c.name}", self.save_wire_id(wire=self.c)))
-                circuit_wires_names.append(self.c.name)
+                    (input, f"{input.name}", self.save_wire_id(wire=input)))
+                circuit_wires_names.append(input.name)
 
         for gate in self.circuit_gates:
             if gate.a.name not in circuit_wires_names:
diff --git a/ariths_gen/core/cgp_circuit.py b/ariths_gen/core/cgp_circuit.py
index cbb5fbc..be1a6cb 100644
--- a/ariths_gen/core/cgp_circuit.py
+++ b/ariths_gen/core/cgp_circuit.py
@@ -123,7 +123,13 @@ class UnsignedCGPCircuit(GeneralCircuit):
             return ConstantWireValue0()
         if i == 1:
             return ConstantWireValue1()
-        return self.vals[i]
+        try:
+            return self.vals[i]
+        except KeyError:
+
+            raise KeyError(f"Key {i} not found in " + ", ".join(
+                [f"{i}: {v}" for i, v in self.vals.items()]
+            ))
 
 
 class SignedCGPCircuit(UnsignedCGPCircuit):
diff --git a/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py b/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py
index eac7a40..c24c2c2 100644
--- a/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py
+++ b/ariths_gen/core/logic_gate_circuits/logic_gate_circuit.py
@@ -33,14 +33,16 @@ class MultipleInputLogicGate():
         prefix (str, optional): Prefix used to name inner composite logic gates. Defaults to "".
     """
     def __init__(self, a: Bus, two_input_gate_cls, parent_component: object, prefix: str = ""):
+        i = 0
         while a.N != 1:
             N = math.floor(a.N/2)
             out_wires = []
             # Creation of composite two input logic gates from bus `a`'s bit pairs and addition of generated blocks outputs for next iteration
             for bus_index in range(0, N):
-                gate = two_input_gate_cls(a=a.get_wire(bus_index), b=a.get_wire(bus_index+N), prefix=prefix+str(parent_component.get_instance_num(cls=two_input_gate_cls, count_disabled_gates=False)), parent_component=parent_component)
+                gate = two_input_gate_cls(a=a.get_wire(bus_index), b=a.get_wire(bus_index+N), prefix=prefix+ "_" + str(i) + "_" + str(parent_component.get_instance_num(cls=two_input_gate_cls, count_disabled_gates=False)), parent_component=parent_component)
                 parent_component.add_component(gate)
                 out_wires.append(gate.out)
+                i += 1
 
             # In case bus `a` has odd number of wires
             if a.N % 2 != 0:
@@ -110,6 +112,8 @@ class TwoInputLogicGate():
         Returns:
             str: C code description of logic gate's Boolean function (with bitwise shifted inputs).
         """
+        if self.out.is_const():
+            return self.out.get_wire_value_c_flat()
         return f"{self.a.get_wire_value_c_flat()} {self.operator} {self.b.get_wire_value_c_flat()}"
 
     def get_declaration_c_flat(self):
@@ -206,6 +210,8 @@ class TwoInputLogicGate():
         # No gate logic is generated if one of the inputs is a wire with constant value.
         # I.e. either the constant or the second input wire is propagated to the output for the corresponding logic gate's logic function.
         if self.disable_generation:
+            #return f"  {self.out.prefix} = {self.get_function_c()} # DD {self.prefix} \n"
+
             return ""
         else:
             return f"  {self.out.prefix} = {self.get_function_c()}\n"
diff --git a/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py
index 4665b50..439286c 100644
--- a/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py
+++ b/ariths_gen/multi_bit_circuits/adders/carry_lookahead_adder.py
@@ -109,14 +109,14 @@ class UnsignedCarryLookaheadAdder(ArithmeticCircuit):
 
                     # For each pg pair values algorithmically combine two input AND gates to replace multiple input gates (resolves fan-in issue)
                     pg_wires = Bus(wires_list=composite_wires)
-                    multi_bit_and_gate = MultipleInputLogicGate(a=pg_wires, two_input_gate_cls=AndGate, prefix=self.prefix+"_and", parent_component=self)
+                    multi_bit_and_gate = MultipleInputLogicGate(a=pg_wires, two_input_gate_cls=AndGate, prefix=self.prefix+f"_and{block_n}_{i}_{g_index}", parent_component=self)
                     composite_or_gates_inputs.append(multi_bit_and_gate.out)
 
                 # Final OR gates cascade using generated AND gates output wires
                 composite_or_wires = Bus(wires_list=composite_or_gates_inputs)
-                multi_bit_or_gate = MultipleInputLogicGate(a=composite_or_wires, two_input_gate_cls=OrGate, prefix=self.prefix+"_or", parent_component=self)
+                multi_bit_or_gate = MultipleInputLogicGate(a=composite_or_wires, two_input_gate_cls=OrGate, prefix=self.prefix+f"_orred{block_n}_{i}_{g_index}_", parent_component=self)
                 # Carry bit generation
-                obj_cout_or = OrGate(pg_block.get_generate_wire(), multi_bit_or_gate.out, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=OrGate, count_disabled_gates=False)), parent_component=self)
+                obj_cout_or = OrGate(pg_block.get_generate_wire(), multi_bit_or_gate.out, prefix=self.prefix+f"_or{block_n}_{i}_{g_index}_"+str(self.get_instance_num(cls=OrGate, count_disabled_gates=False)), parent_component=self)
                 self.add_component(obj_cout_or)
                 # Updating cin for the the next cla block/sum XOR
                 cin = obj_cout_or.out
diff --git a/ariths_gen/multi_bit_circuits/others/__init__.py b/ariths_gen/multi_bit_circuits/others/__init__.py
index 44ed65b..de090f3 100644
--- a/ariths_gen/multi_bit_circuits/others/__init__.py
+++ b/ariths_gen/multi_bit_circuits/others/__init__.py
@@ -8,5 +8,7 @@ from ariths_gen.multi_bit_circuits.others.bit_reduce import (
 )
 
 from ariths_gen.multi_bit_circuits.others.compare import (
-    UnsignedCompareLT
-)
\ No newline at end of file
+    UnsignedCompareLT, UnsignedCompareLTE, UnsignedCompareGT, UnsignedCompareGTE
+)
+
+from ariths_gen.multi_bit_circuits.others.popcount_compare import PopCountCompare
\ No newline at end of file
diff --git a/ariths_gen/multi_bit_circuits/others/bit_reduce.py b/ariths_gen/multi_bit_circuits/others/bit_reduce.py
index 45da4d7..bd0cd8b 100644
--- a/ariths_gen/multi_bit_circuits/others/bit_reduce.py
+++ b/ariths_gen/multi_bit_circuits/others/bit_reduce.py
@@ -68,8 +68,8 @@ class BitReduce(GeneralCircuit):
                 for i, j in enumerate(range(half, a.N)):
                     c_in[i] = a[j]
 
-                b = create_tree(b_in, depth=depth + 1, branch = "A")
-                c = create_tree(c_in, depth= depth + 1, branch = "B")
+                b = create_tree(b_in, depth=depth + 1, branch = branch + "A")
+                c = create_tree(c_in, depth= depth + 1, branch = branch + "B")
                 d = gate(a=b, b=c, prefix = f"{self.prefix}_red_{branch}_{depth}")
                 self.add_component(d)
                 return d.out
diff --git a/ariths_gen/multi_bit_circuits/others/compare.py b/ariths_gen/multi_bit_circuits/others/compare.py
index 6c62970..6e92ce1 100644
--- a/ariths_gen/multi_bit_circuits/others/compare.py
+++ b/ariths_gen/multi_bit_circuits/others/compare.py
@@ -44,7 +44,6 @@ class UnsignedCompareLT(GeneralCircuit):
 
     
     Returns true if a < b
-
     """
 
     def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs):
@@ -52,32 +51,144 @@ class UnsignedCompareLT(GeneralCircuit):
         self.b = b
         self.N = max(a.N, b.N)
 
-        #print("outc", outc)
         super().__init__(name=name, prefix=prefix, 
                          inputs = [self.a, self.b], out_N=1)
 
-
-        self.a.bus_extend(self.N, prefix=a.prefix)
-        self.b.bus_extend(self.N, prefix=b.prefix)
-        
-
         # create wires
         psum = ConstantWireValue1()
 
         res = Bus(N = self.N, prefix=self.prefix + "res")
-        
 
         for i in reversed(range(self.N)):
-
-            i1 = self.add_component(NotGate(self.a[i], f"{self.prefix}_i1_{i}")).out
-            i2 = self.b[i]
+            iA = self.a[i] if i < self.a.N else ConstantWireValue0()
+            iB = self.b[i] if i < self.b.N else ConstantWireValue0()
+            
+            i1 = self.add_component(NotGate(iA, f"{self.prefix}_i1_{i}")).out
+            i2 = iB
 
             and1 = self.add_component(AndGate(i1, i2, f"{self.prefix}_and1_{i}")).out
             res[i] = self.add_component(AndGate(and1, psum, f"{self.prefix}_and2_{i}")).out
 
-            pi = self.add_component(XnorGate(self.a[i], self.b[i], f"{self.prefix}_pi_{i}")).out
+            pi = self.add_component(XnorGate(iA, iB, f"{self.prefix}_pi_{i}", parent_component=self)).out
             psum = self.add_component(AndGate(pi, psum, f"{self.prefix}_psum_{i}")).out
 
 
-        self.out = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred")).out
-        #self.out.connect_bus(sumbus  )
\ No newline at end of file
+        red = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred", inner_component=True))
+        self.out.connect_bus(red.out)
+
+
+class UnsignedCompareLTE(GeneralCircuit):
+    """Class representing unsigned compare
+    
+    Returns true if a <= b
+    """
+
+    def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs):
+        self.a = a
+        self.b = b
+        self.N = max(a.N, b.N)
+
+        super().__init__(name=name, prefix=prefix, 
+                         inputs = [self.a, self.b], out_N=1)
+
+        # create wires
+        psum = ConstantWireValue1()
+
+        res = Bus(N = self.N + 1, prefix=self.prefix + "res")
+
+        for i in reversed(range(self.N)):
+            iA = self.a[i] if i < self.a.N else ConstantWireValue0()
+            iB = self.b[i] if i < self.b.N else ConstantWireValue0()
+            
+            i1 = self.add_component(NotGate(iA, f"{self.prefix}_i1_{i}")).out
+            i2 = iB
+
+            and1 = self.add_component(AndGate(i1, i2, f"{self.prefix}_and1_{i}")).out
+            res[i] = self.add_component(AndGate(and1, psum, f"{self.prefix}_and2_{i}")).out
+
+            pi = self.add_component(XnorGate(iA, iB, f"{self.prefix}_pi_{i}", parent_component=self)).out
+            psum = self.add_component(AndGate(pi, psum, f"{self.prefix}_psum_{i}")).out
+
+        res[self.N] = psum # or all equal (xor)
+
+        red = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred", inner_component=True))
+
+        self.out.connect_bus(red.out)
+
+
+
+class UnsignedCompareGT(GeneralCircuit):
+    """Class representing unsigned compare
+
+    
+    Returns true if a < b
+    """
+
+    def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gt", **kwargs):
+        self.a = a
+        self.b = b
+        self.N = max(a.N, b.N)
+
+        super().__init__(name=name, prefix=prefix, 
+                         inputs = [self.a, self.b], out_N=1)
+
+        # create wires
+        psum = ConstantWireValue1()
+
+        res = Bus(N = self.N, prefix=self.prefix + "res")
+
+        for i in reversed(range(self.N)):
+            iA = self.a[i] if i < self.a.N else ConstantWireValue0()
+            iB = self.b[i] if i < self.b.N else ConstantWireValue0()
+            
+            i1 = iA
+            i2 = self.add_component(NotGate(iB, f"{self.prefix}_i2_{i}")).out
+
+            and1 = self.add_component(AndGate(i1, i2, f"{self.prefix}_and1_{i}")).out
+            res[i] = self.add_component(AndGate(and1, psum, f"{self.prefix}_and2_{i}")).out
+
+            pi = self.add_component(XnorGate(iA, iB, f"{self.prefix}_pi_{i}", parent_component=self)).out
+            psum = self.add_component(AndGate(pi, psum, f"{self.prefix}_psum_{i}")).out
+
+
+        red = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred", inner_component=True))
+        self.out.connect_bus(red.out)
+
+
+class UnsignedCompareGTE(GeneralCircuit):
+    """Class representing unsigned compare
+    
+    Returns true if a <= b
+    """
+
+    def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_gte", **kwargs):
+        self.a = a
+        self.b = b
+        self.N = max(a.N, b.N)
+
+        super().__init__(name=name, prefix=prefix, 
+                         inputs = [self.a, self.b], out_N=1)
+
+        # create wires
+        psum = ConstantWireValue1()
+
+        res = Bus(N = self.N + 1, prefix=self.prefix + "res")
+
+        for i in reversed(range(self.N)):
+            iA = self.a[i] if i < self.a.N else ConstantWireValue0()
+            iB = self.b[i] if i < self.b.N else ConstantWireValue0()
+            
+            i1 = iA
+            i2 = self.add_component(NotGate(iB, f"{self.prefix}_i1_{i}", parent_component=self)).out
+
+            and1 = self.add_component(AndGate(i1, i2, f"{self.prefix}_and1_{i}", parent_component=self)).out
+            res[i] = self.add_component(AndGate(and1, psum, f"{self.prefix}_and2_{i}", parent_component=self)).out
+
+            pi = self.add_component(XnorGate(iA, iB, f"{self.prefix}_pi_{i}", parent_component=self)).out
+            psum = self.add_component(AndGate(pi, psum, f"{self.prefix}_psum_{i}", parent_component=self)).out
+
+        res[self.N] = psum # or all equal (xor)
+        
+        red = self.add_component(OrReduce(res, prefix=f"{self.prefix}_orred", inner_component=True))
+
+        self.out.connect_bus(red.out)
\ No newline at end of file
diff --git a/ariths_gen/multi_bit_circuits/others/popcount.py b/ariths_gen/multi_bit_circuits/others/popcount.py
index cdca327..459365f 100644
--- a/ariths_gen/multi_bit_circuits/others/popcount.py
+++ b/ariths_gen/multi_bit_circuits/others/popcount.py
@@ -78,8 +78,8 @@ class UnsignedPopCount(GeneralCircuit):
                 for i, j in enumerate(range(half, a.N)):
                     c_in[i] = a[j]
 
-                b = create_tree(b_in, depth=depth + 1, branch = "A")
-                c = create_tree(c_in, depth= depth + 1, branch = "B")
+                b = create_tree(b_in, depth=depth + 1, branch = branch + "A")
+                c = create_tree(c_in, depth= depth + 1, branch = branch + "B")
                 d = self.adder(a=b, b=c, prefix = f"{self.prefix}_add{branch}_{depth}")
                 self.add_component(d)
                 return d.out
diff --git a/ariths_gen/multi_bit_circuits/others/popcount_compare.py b/ariths_gen/multi_bit_circuits/others/popcount_compare.py
new file mode 100644
index 0000000..1f2095c
--- /dev/null
+++ b/ariths_gen/multi_bit_circuits/others/popcount_compare.py
@@ -0,0 +1,81 @@
+"""
+
+"""
+
+from ariths_gen.multi_bit_circuits.others import UnsignedPopCount
+from ariths_gen.multi_bit_circuits.others.compare import UnsignedCompareGTE
+from ariths_gen.wire_components import (
+    Wire,
+    ConstantWireValue0,
+    ConstantWireValue1,
+    Bus,
+    wires
+)
+from ariths_gen.core.arithmetic_circuits import (
+    ArithmeticCircuit,
+    GeneralCircuit,
+    MultiplierCircuit
+)
+
+from ariths_gen.core.logic_gate_circuits import (
+    MultipleInputLogicGate
+)
+from ariths_gen.one_bit_circuits.one_bit_components import (
+    HalfAdder,
+    FullAdder,
+    FullAdderP,
+    TwoOneMultiplexer
+)
+from ariths_gen.one_bit_circuits.logic_gates import (
+    AndGate,
+    NandGate,
+    OrGate,
+    NorGate,
+    XorGate,
+    XnorGate,
+    NotGate
+)
+
+from ariths_gen.multi_bit_circuits.others import OrReduce
+
+
+from math import log2, ceil
+
+class PopCountCompare(GeneralCircuit):
+    """Class representing a circiut
+      if number of ones in a is larger or equal than number of ones in b
+
+         │ │ │ │         │ │ │ │ │ 
+         ▼ ▼ ▼ ▼         ▼ ▼ ▼ ▼ ▼ 
+        ┌───────┐       ┌─────────┐
+        │ popcnt│       │ popcnt  │
+        └──┬────┘       └─────┬───┘
+           │                  │    
+           └───────┐   ┌──────┘    
+                ┌──▼───▼──┐         
+                │   <=    │         
+                └────┬────┘         
+                     │             
+                     ▼             
+    """
+
+    def __init__(self, a: Bus, b: Bus, prefix : str = "", name : str = "cmp_lt", **kwargs):
+        self.a = a
+        self.b = b
+        
+        super().__init__(name=name, prefix=prefix, 
+                         inputs = [self.a, self.b], out_N=1)
+
+        p1 = self.add_component(UnsignedPopCount(self.a, 
+                                                 prefix=f"{prefix}_popcount1",
+                                                 inner_component=True)).out
+        p2 = self.add_component(UnsignedPopCount(self.b, 
+                                                 prefix=f"{prefix}_popcount2",
+                                                 inner_component=True)).out
+
+        N = max(p1.N, p2.N)
+        p1.bus_extend(N)
+        p2.bus_extend(N)
+
+        red = self.add_component(UnsignedCompareGTE(p1, p2, prefix=f"{prefix}_cmp", inner_component = True))
+        self.out.connect_bus(red.out)
diff --git a/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py b/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py
index f0c74db..822b850 100644
--- a/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py
+++ b/ariths_gen/one_bit_circuits/logic_gates/logic_gates.py
@@ -92,7 +92,8 @@ class NandGate(TwoInputInvertedLogicGate):
         # If constant input is present, logic gate is not generated and corresponding
         # input value is propagated to the output to connect to other components
         if a.is_const() and a.value == 1:
-            output = NotGate(a=b, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=b, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -100,7 +101,8 @@ class NandGate(TwoInputInvertedLogicGate):
             self.out = ConstantWireValue1()
             self.disable_generation = True
         elif b.is_const() and b.value == 1:
-            output = NotGate(a=a, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=a, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -217,7 +219,8 @@ class NorGate(TwoInputInvertedLogicGate):
             self.out = ConstantWireValue0()
             self.disable_generation = True
         elif a.is_const() and a.value == 0:
-            output = NotGate(a=b, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=b, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -225,7 +228,8 @@ class NorGate(TwoInputInvertedLogicGate):
             self.out = ConstantWireValue0()
             self.disable_generation = True
         elif b.is_const() and b.value == 0:
-            output = NotGate(a=a, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=a, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -277,7 +281,8 @@ class XorGate(TwoInputLogicGate):
         # If constant input is present, logic gate is not generated and corresponding
         # input value is propagated to the output to connect to other components
         if a.is_const() and a.value == 1:
-            output = NotGate(a=b, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=b, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -285,7 +290,8 @@ class XorGate(TwoInputLogicGate):
             self.out = b
             self.disable_generation = True
         elif b.is_const() and b.value == 1:
-            output = NotGate(a=a, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=a, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -343,7 +349,8 @@ class XnorGate(TwoInputInvertedLogicGate):
             self.out = b
             self.disable_generation = True
         elif a.is_const() and a.value == 0:
-            output = NotGate(a=b, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=b, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
@@ -351,7 +358,8 @@ class XnorGate(TwoInputInvertedLogicGate):
             self.out = a
             self.disable_generation = True
         elif b.is_const() and b.value == 0:
-            output = NotGate(a=a, prefix=prefix, outid=outid, parent_component=parent_component)
+            assert self.parent_component, "Parent component for gate {self} is not defined"
+            output = NotGate(a=a, prefix=prefix + "_not", outid=outid, parent_component=parent_component)
             self.parent_component.add_component(output) if parent_component is not None else None
             self.out = output.out
             self.disable_generation = True
diff --git a/ariths_gen/wire_components/wires.py b/ariths_gen/wire_components/wires.py
index c34240b..63d8267 100644
--- a/ariths_gen/wire_components/wires.py
+++ b/ariths_gen/wire_components/wires.py
@@ -17,6 +17,9 @@ class Wire():
         self.prefix = name if prefix == "" else prefix
         self.parent_bus = parent_bus
 
+    def __str__(self):
+        return f"wire{self.name}{self.value}{self.index}"
+
     @staticmethod
     def is_const():
         """Information whether wire carries constant value.
diff --git a/tests/test_all.py b/tests/test_all.py
index c8cd777..48cf85d 100644
--- a/tests/test_all.py
+++ b/tests/test_all.py
@@ -348,8 +348,8 @@ def test_wire_as_bus():
         def __init__(self, a: Wire, b: Wire, c: Bus, prefix="test_circuit", **kwargs):
             super().__init__(prefix=prefix, name="test_circuit", inputs=[a, b, c], out_N=1, **kwargs)
             g = self.add_component(AndGate(a, b, prefix="g2"))
-            g2 = self.add_component(AndGate(g.out, c[0], prefix="g2"))
-            g3 = self.add_component(AndGate(g2.out, c[1], prefix="g2"))
+            g2 = self.add_component(AndGate(g.out, c[0], prefix="g3"))
+            g3 = self.add_component(AndGate(g2.out, c[1], prefix="g4"))
             self.out[0] = g3.out
 
     circ = test_circuit(Wire("a"), Wire("b"), Bus("c", 2), "c1")
diff --git a/tests/test_compare.py b/tests/test_compare.py
index 02e1312..4420d9c 100644
--- a/tests/test_compare.py
+++ b/tests/test_compare.py
@@ -8,15 +8,18 @@ from ariths_gen.wire_components import (
 from ariths_gen.core.arithmetic_circuits import GeneralCircuit
 
 from ariths_gen.multi_bit_circuits.others import (
-    UnsignedCompareLT
+    UnsignedCompareLT, UnsignedCompareLTE, UnsignedCompareGT, UnsignedCompareGTE
 )
 
+from ariths_gen.core.cgp_circuit import UnsignedCGPCircuit, SignedCGPCircuit
+
+
 import numpy as np
 import math
 from io import StringIO
 
 
-def test_compare():
+def test_compare_lt_same():
     """ Test unsigned comparator """
     N = 8
 
@@ -27,9 +30,39 @@ def test_compare():
 
 
     cmp = UnsignedCompareLT(a=a, b=b)
-    o = StringIO()
     cmp.get_v_code_hier(open("tmp.verilog", "w"))
-    print(o.getvalue())
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av < bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+
+def test_compare_lt_small():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N//2, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**(N //2)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareLT(a=a, b=b)
+    #o = StringIO()
+    cmp.get_python_code_flat(open("tmp.py", "w"))
+    cmp.get_c_code_flat(open("tmp.c", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
 
 #    av = 0
  #   bv = 5
@@ -47,4 +80,289 @@ def test_compare():
     np.testing.assert_array_equal(v, expected)
 
 
-    
\ No newline at end of file
+    
+def test_compare_lte_same():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**N).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareLTE(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av <= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+
+def test_compare_lte_small():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N//2, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**(N //2)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareLTE(a=a, b=b)
+    #o = StringIO()
+    cmp.get_python_code_flat(open("tmp.py", "w"))
+    cmp.get_c_code_flat(open("tmp.c", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
+
+#    av = 0
+ #   bv = 5
+
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av <= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+def test_compare_lte_small2():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N//2, prefix="a")
+    b = Bus(N=N, prefix="b")
+    av = np.arange(2**(N // 2)).reshape(1, -1)
+    bv = np.arange(2**(N)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareLTE(a=a, b=b)
+    #o = StringIO()
+    cmp.get_python_code_flat(open("tmp.py", "w"))
+    cmp.get_c_code_flat(open("tmp.c", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
+
+#    av = 0
+ #   bv = 5
+
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av <= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+def test_compare_gt_same():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**N).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGT(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av > bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+
+def test_compare_gt_small():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N//2, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**(N //2)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGT(a=a, b=b)
+    #o = StringIO()
+    cmp.get_python_code_flat(open("tmp.py", "w"))
+    cmp.get_c_code_flat(open("tmp.c", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
+
+#    av = 0
+ #   bv = 5
+
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av > bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+def test_compare_gte_same():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**N).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGTE(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av >= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+
+def test_compare_gte_small():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N//2, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**(N //2)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGTE(a=a, b=b)
+    #o = StringIO()
+    cmp.get_python_code_flat(open("tmp.py", "w"))
+    cmp.get_c_code_flat(open("tmp.c", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
+
+#    av = 0
+ #   bv = 5
+
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av >= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+
+def test_compare_gte_cgp_same():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**N).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGTE(a=a, b=b)
+    o = StringIO()
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    cmp.get_cgp_code_flat(o)
+    
+    cgp = UnsignedCGPCircuit(o.getvalue(), [N, N])
+
+    v = cgp(av, bv)
+    print("ret = ", v)
+
+    expected = np.array(av >= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+    
+
+def test_compare_gte_cgp_small():
+    """ Test unsigned comparator """
+    N = 8
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N//2, prefix="b")
+    av = np.arange(2**N).reshape(1, -1)
+    bv = np.arange(2**(N //2)).reshape(-1, 1)
+
+
+    cmp = UnsignedCompareGTE(a=a, b=b)
+    o = StringIO()
+    cmp.get_v_code_flat(open("tmp.verilog", "w"))
+    cmp.get_cgp_code_flat(o)
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+    
+    cgp = UnsignedCGPCircuit(o.getvalue(), [N, N // 2])
+
+    v = cgp(av, bv)
+    #cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    #print(o.getvalue())
+
+#    av = 0
+ #   bv = 5
+
+
+    print("ret = ", v)
+
+    expected = np.array(av >= bv).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
\ No newline at end of file
diff --git a/tests/test_popcnt.py b/tests/test_popcnt.py
index 8d66628..936084e 100644
--- a/tests/test_popcnt.py
+++ b/tests/test_popcnt.py
@@ -1,3 +1,4 @@
+from ariths_gen.core.cgp_circuit import UnsignedCGPCircuit
 from ariths_gen.wire_components import (
     Wire,
     ConstantWireValue0,
@@ -47,4 +48,38 @@ def test_popcount():
         np.testing.assert_array_equal(popcnt(av), expected)
 
 
+
+
+
+def test_popcount_cgp():
+    """ Test unsigned adders """
+    N = 7
+
+    for N in [3, 7, 8, 9, 16]:
+        a = Bus(N=N, prefix="a")
+        av = np.arange(2**N)
+
+
+        popcnt = UnsignedPopCount(a=a)
+        o = StringIO()
+        popcnt.get_cgp_code_flat(o)
+        cgp = UnsignedCGPCircuit(o.getvalue(), [N])
+        v = cgp(av)
+
+
+        print(popcnt(av))
+
+
+        # conv to binary
+        r = []
+        a_s = av.copy()
+        for i in range(N):
+            r.append(a_s % 2)
+            a_s = a_s // 2
+        r = np.dstack(r).reshape(-1, N)
+        print("r = ", r)
+        expected = np.sum(r, axis=1)
+
+        np.testing.assert_array_equal(v, expected)
+
     
\ No newline at end of file
diff --git a/tests/test_popcount_compare.py b/tests/test_popcount_compare.py
new file mode 100644
index 0000000..3f02ede
--- /dev/null
+++ b/tests/test_popcount_compare.py
@@ -0,0 +1,169 @@
+from ariths_gen.wire_components import (
+    Wire,
+    ConstantWireValue0,
+    ConstantWireValue1,
+    Bus
+)
+
+from ariths_gen.core.arithmetic_circuits import GeneralCircuit
+
+from ariths_gen.multi_bit_circuits.others import (
+    PopCountCompare
+)
+
+from ariths_gen.core.cgp_circuit import UnsignedCGPCircuit, SignedCGPCircuit
+
+
+import numpy as np
+import math
+from io import StringIO
+
+from itertools import product
+
+def test_popcountcompare_same():
+    N = 10
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N, prefix="b")
+
+    test_cases = list(product(list(range(2**N)), repeat=2))
+    all = np.array(test_cases)
+
+    print(all)
+    av = all[:, 0]
+    bv = all[:, 1]
+    def popcnt(x):
+        mask = x & (2**np.arange(N)).reshape(-1, 1)
+        return np.sum(mask > 0, axis=0)
+    cnta = (popcnt(av))
+    cntb = (popcnt(bv))
+    print(cnta)
+    print(cntb)
+
+
+
+    cmp = PopCountCompare(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+
+    expected = np.array(cnta >= cntb).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+def test_popcountcompare_small():
+    N = 10
+
+    a = Bus(N=N, prefix="a")
+    b = Bus(N=N // 2, prefix="b")
+
+    test_cases = list(product(range(2**N), range(2**(N//2))))
+    all = np.array(test_cases)
+
+    print(all)
+    av = all[:, 0]
+    bv = all[:, 1]
+    def popcnt(x):
+        mask = x & (2**np.arange(N)).reshape(-1, 1)
+        return np.sum(mask > 0, axis=0)
+    cnta = (popcnt(av))
+    cntb = (popcnt(bv))
+
+
+    cmp = PopCountCompare(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+
+    expected = np.array(cnta >= cntb).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+def test_popcountcompare_small2():
+    N = 10
+
+    a = Bus(N=N // 2, prefix="a")
+    b = Bus(N=N, prefix="b")
+
+    test_cases = list(product( range(2**(N//2)), range(2**N)))
+    all = np.array(test_cases)
+
+    print(all)
+    av = all[:, 0]
+    bv = all[:, 1]
+    def popcnt(x):
+        mask = x & (2**np.arange(N)).reshape(-1, 1)
+        return np.sum(mask > 0, axis=0)
+    cnta = (popcnt(av))
+    cntb = (popcnt(bv))
+
+
+    cmp = PopCountCompare(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+
+    v = cmp(av, bv)
+    print("ret = ", v)
+
+
+    expected = np.array(cnta >= cntb).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)
+
+
+
+def test_popcountcompare_small2_cgp():
+    N = 10
+
+    a = Bus(N=N // 2, prefix="a")
+    b = Bus(N=N, prefix="b")
+
+    test_cases = list(product( range(2**(N//2)), range(2**N)))
+    all = np.array(test_cases)
+
+    print(all)
+    av = all[:, 0]
+    bv = all[:, 1]
+    def popcnt(x):
+        mask = x & (2**np.arange(N)).reshape(-1, 1)
+        return np.sum(mask > 0, axis=0)
+    cnta = (popcnt(av))
+    cntb = (popcnt(bv))
+
+
+    cmp = PopCountCompare(a=a, b=b)
+    cmp.get_v_code_hier(open("tmp.verilog", "w"))
+    cmp.get_cgp_code_flat(open("tmp.cgp", "w"))
+
+    o = StringIO()
+    cmp.get_cgp_code_flat(o)
+    cgp = UnsignedCGPCircuit(o.getvalue(), [N//2, N])
+
+    v = cgp(av, bv)
+    print("ret = ", v)
+
+
+    expected = np.array(cnta >= cntb).astype(int)
+
+    print("expected = ", expected)
+        
+    #expected = np.sum(r, axis=1)
+
+    np.testing.assert_array_equal(v, expected)