Comparing multiple elements of an array in Verilog is indeed possible and is a common requirement in digital design. This article, brought to you by COMPARE.EDU.VN, will delve into the methods and considerations for performing such comparisons efficiently and effectively. You’ll gain a comprehensive understanding, enabling you to implement complex comparison logic with confidence and clarity. This will involve exploring different approaches, including the use of loops, generate statements, and specialized hardware structures, all while maintaining efficient resource utilization and timing performance.
Table of Contents
- Understanding Array Comparisons in Verilog
- 1.1. What is Verilog?
- 1.2. What is an Array in Verilog?
- 1.3. Why Compare Multiple Array Elements?
- Methods for Comparing Multiple Array Elements
- 2.1. Using Loops for Comparison
- 2.1.1.
for
Loops - 2.1.2.
while
Loops - 2.1.3. Considerations When Using Loops
- 2.1.1.
- 2.2. Using Generate Statements for Parallel Comparison
- 2.2.1. Understanding Generate Blocks
- 2.2.2. Implementing Parallel Comparison with Generate Statements
- 2.2.3. Advantages and Limitations of Generate Statements
- 2.3. Implementing Comparison with Specialized Hardware
- 2.3.1. Comparators and Adders
- 2.3.2. Implementing Comparison Trees
- 2.3.3. Trade-offs Between Different Hardware Structures
- 2.1. Using Loops for Comparison
- Verilog Code Examples
- 3.1. Comparing Adjacent Elements Using a Loop
- 3.2. Comparing All Elements to a Threshold Value Using a Loop
- 3.3. Finding the Maximum Value in an Array Using a Loop
- 3.4. Parallel Comparison of Array Elements Using Generate Statements
- Optimizing Array Comparison for Performance
- 4.1. Reducing Comparison Latency
- 4.1.1. Pipelining
- 4.1.2. Parallel Processing
- 4.2. Minimizing Resource Utilization
- 4.2.1. Sharing Comparators
- 4.2.2. Using Efficient Data Structures
- 4.3. Balancing Latency and Resource Utilization
- 4.1. Reducing Comparison Latency
- Case Studies and Practical Applications
- 5.1. Image Processing
- 5.2. Digital Signal Processing (DSP)
- 5.3. Network Packet Processing
- Simulation and Verification
- 6.1. Writing Testbenches for Array Comparison
- 6.2. Using Assertions for Verification
- 6.3. Debugging Array Comparison Logic
- Common Pitfalls and How to Avoid Them
- 7.1. Incorrect Loop Termination
- 7.2. Race Conditions
- 7.3. Overflow and Underflow Issues
- Advanced Techniques
- 8.1. Using SystemVerilog for Complex Comparisons
- 8.2. Implementing Custom Comparison Functions
- 8.3. Dynamic Array Comparisons
- Future Trends in Verilog Array Comparison
- Conclusion
- FAQ
- References
1. Understanding Array Comparisons in Verilog
Can you effectively compare multiple array elements in Verilog for digital design? Yes, you can compare multiple elements of an array in Verilog using various methods. Understanding the fundamental principles of array comparisons and their importance in hardware description languages (HDLs) like Verilog allows digital design engineers to efficiently implement such comparisons. This section provides an overview of Verilog, arrays, and the significance of comparing array elements, setting the stage for more detailed exploration. compare.edu.vn is committed to offering the best comparison in tech.
1.1. What is Verilog?
Verilog is a hardware description language (HDL) used to model, design, simulate, and verify electronic systems. It allows designers to describe digital circuits at various levels of abstraction, from the gate level to the behavioral level. Verilog is essential for designing complex digital systems like microprocessors, memory controllers, and communication interfaces. It provides a structured way to represent hardware components and their interconnections, enabling simulation and synthesis to create physical implementations. According to research from the IEEE, Verilog’s flexibility and broad industry support make it a primary language for digital design.
1.2. What is an Array in Verilog?
In Verilog, an array is a collection of variables of the same data type, grouped under a single name. Arrays are used to store and manipulate multiple data elements efficiently. For example, you can define an array of registers, wires, or integers. Arrays can be one-dimensional or multi-dimensional, allowing you to represent complex data structures. The syntax for declaring an array in Verilog includes specifying the data type and the range of indices. For instance, reg [7:0] my_array [0:255]
declares an array named my_array
that holds 256 registers, each 8 bits wide.
Alt text: Verilog array declaration showing a register array with specified width and range, important for memory and data structure implementation
1.3. Why Compare Multiple Array Elements?
Comparing multiple array elements is a common operation in digital design with various applications. For example:
- Finding the Maximum or Minimum Value: In signal processing or data analysis, you often need to find the largest or smallest value in a set of data stored in an array.
- Sorting: Sorting algorithms require comparing multiple elements to arrange them in a specific order.
- Pattern Matching: In network packet processing or image processing, you might need to compare array elements to identify specific patterns.
- Data Validation: Ensuring data integrity might involve comparing array elements against predefined thresholds or expected values.
- Conditional Execution: Making decisions based on the relationship between multiple array elements, such as triggering an event when certain conditions are met.
Comparing multiple array elements allows you to implement complex decision-making logic within your digital designs, enabling efficient and flexible hardware implementations.
2. Methods for Comparing Multiple Array Elements
What are the primary methods for comparing multiple elements of an array in Verilog? There are several methods to compare multiple array elements in Verilog, including using loops, generate statements, and specialized hardware structures. Each method offers different trade-offs in terms of code complexity, performance, and resource utilization. The choice of method depends on the specific requirements of your design, such as speed, area, and power consumption.
2.1. Using Loops for Comparison
How can loops be used to compare multiple array elements in Verilog? Loops are a straightforward way to iterate through array elements and perform comparisons. Verilog supports for
and while
loops, which can be used to compare array elements sequentially. Loops are suitable for designs where performance is not critical, and code simplicity is preferred.
2.1.1. for
Loops
The for
loop is commonly used to iterate through array elements when the number of iterations is known in advance. The syntax for a for
loop in Verilog is as follows:
for (initial_assignment; condition; step_assignment) begin
// Code to be executed in each iteration
end
Example:
module array_compare_for (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
max_value <= data_array[0]; // Initialize with the first element
for (i = 1; i < 8; i = i + 1) begin
if (data_array[i] > max_value) begin
max_value <= data_array[i];
end
end
end
end
endmodule
In this example, the for
loop iterates through the data_array
, comparing each element to the current max_value
. If an element is larger than max_value
, it updates max_value
accordingly.
2.1.2. while
Loops
The while
loop is useful when the number of iterations is not known in advance and depends on a specific condition. The syntax for a while
loop in Verilog is:
while (condition) begin
// Code to be executed as long as the condition is true
end
Example:
module array_compare_while (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
i <= 0;
end else begin
while (i < 8) begin
if (data_array[i] > max_value) begin
max_value <= data_array[i];
end
i <= i + 1;
end
end
end
endmodule
Here, the while
loop continues as long as the index i
is less than 8, comparing each element to max_value
and updating it if necessary.
2.1.3. Considerations When Using Loops
While loops are simple to implement, they have some drawbacks:
- Sequential Execution: Loops execute sequentially, which can be slow for large arrays. Each comparison depends on the result of the previous one.
- Timing Constraints: Meeting timing constraints can be challenging with loops, especially in high-speed designs. The synthesis tool needs to ensure that each iteration of the loop can be completed within the clock cycle.
- Resource Utilization: Loops might not be the most efficient in terms of resource utilization, as they require the same hardware to be used repeatedly for each iteration.
Therefore, loops are best suited for designs where performance is not critical, and code simplicity is more important.
2.2. Using Generate Statements for Parallel Comparison
When should generate statements be used to compare multiple array elements in Verilog? Generate statements offer a way to create parallel hardware structures in Verilog, enabling you to compare multiple array elements simultaneously. This approach can significantly improve performance compared to using loops.
2.2.1. Understanding Generate Blocks
Generate blocks are a powerful feature in Verilog that allows you to create multiple instances of hardware modules or logic based on a parameter or condition. Generate blocks are evaluated at compile time, meaning that the generated hardware structure is fixed before simulation or synthesis.
The syntax for a generate block is as follows:
generate
if (condition) begin : block_name
// Code to be generated if the condition is true
end else begin : another_block_name
// Code to be generated if the condition is false
end
endgenerate
You can also use for
loops within generate blocks to create multiple instances of a module or logic.
2.2.2. Implementing Parallel Comparison with Generate Statements
To compare array elements in parallel using generate statements, you can create multiple comparator instances, each comparing a pair of array elements. The results of these comparisons can then be combined to find the maximum or minimum value.
Example:
module array_compare_generate (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
reg [7:0] compare_tree [0:3];
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
// First level of comparison
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
compare_tree[i] <= data_array[2*i];
end else begin
compare_tree[i] <= data_array[2*i+1];
end
end
// Second level of comparison
for (i = 0; i < 2; i = i + 1) begin
if (compare_tree[2*i] > compare_tree[2*i+1]) begin
compare_tree[i+4] <= compare_tree[2*i];
end else begin
compare_tree[i+4] <= compare_tree[2*i+1];
end
end
// Final comparison
if (compare_tree[4] > compare_tree[5]) begin
max_value <= compare_tree[4];
end else begin
max_value <= compare_tree[5];
end
end
end
endmodule
In this example, the generate statements create a tree of comparators. Each comparator compares a pair of array elements, and the results are combined until the maximum value is found. This approach allows for parallel execution, reducing the comparison latency.
2.2.3. Advantages and Limitations of Generate Statements
Advantages of using generate statements:
- Parallel Execution: Generate statements enable parallel execution of comparisons, reducing latency.
- Improved Performance: The parallel structure can significantly improve the performance of array comparisons.
- Fixed Hardware Structure: The hardware structure is fixed at compile time, allowing for better optimization by the synthesis tool.
Limitations of using generate statements:
- Code Complexity: Generate statements can make the code more complex and harder to understand, especially for large arrays.
- Resource Utilization: Parallel comparisons can increase resource utilization, as they require multiple comparator instances.
- Limited Flexibility: The hardware structure is fixed at compile time, making it difficult to adapt to changing array sizes or comparison criteria.
Generate statements are best suited for designs where performance is critical, and the array size and comparison criteria are known in advance.
Alt text: Verilog generate statement example showing conditional hardware generation based on parameters, crucial for configurable and scalable designs
2.3. Implementing Comparison with Specialized Hardware
How can specialized hardware, like comparators and adders, be used for array comparison? You can use specialized hardware components, such as comparators and adders, to implement array comparisons in Verilog. These components can be interconnected to create comparison trees or other parallel structures that improve performance and reduce latency.
2.3.1. Comparators and Adders
- Comparators: A comparator is a digital circuit that compares two input values and outputs whether one value is greater than, less than, or equal to the other. Comparators are fundamental building blocks for array comparison logic.
- Adders: Adders can be used to implement more complex comparison functions, such as finding the difference between two values or calculating a weighted sum.
2.3.2. Implementing Comparison Trees
A comparison tree is a hierarchical structure of comparators that compares multiple array elements in parallel. The first level of the tree compares pairs of elements, and subsequent levels compare the results of the previous level until the final result is obtained.
Example:
module comparator (
input [7:0] a,
input [7:0] b,
output reg greater
);
always @(*) begin
if (a > b) begin
greater <= 1;
end else begin
greater <= 0;
end
end
endmodule
module comparison_tree (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
wire [7:0] level1 [0:3];
wire greater1 [0:3];
wire [7:0] level2 [0:1];
wire greater2 [0:1];
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : gen_level1
comparator comp1 (
.a(data_array[2*i]),
.b(data_array[2*i+1]),
.greater(greater1[i])
);
assign level1[i] = (greater1[i]) ? data_array[2*i] : data_array[2*i+1];
end
endgenerate
generate
for (i = 0; i < 2; i = i + 1) begin : gen_level2
comparator comp2 (
.a(level1[2*i]),
.b(level1[2*i+1]),
.greater(greater2[i])
);
assign level2[i] = (greater2[i]) ? level1[2*i] : level1[2*i+1];
end
endgenerate
comparator comp_final (
.a(level2[0]),
.b(level2[1]),
.greater(greater2[2])
);
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
max_value <= (greater2[2]) ? level2[0] : level2[1];
end
end
endmodule
In this example, the comparator
module compares two input values, and the comparison_tree
module uses multiple instances of the comparator
to find the maximum value in the array.
2.3.3. Trade-offs Between Different Hardware Structures
Different hardware structures offer different trade-offs in terms of performance, resource utilization, and complexity.
- Parallel Comparators: Offer the highest performance but also consume the most resources.
- Comparison Trees: Provide a good balance between performance and resource utilization.
- Sequential Comparators: Consume the least resources but offer the lowest performance.
The choice of hardware structure depends on the specific requirements of your design and the available resources.
3. Verilog Code Examples
Can you provide specific Verilog code examples for comparing multiple array elements? Here are several Verilog code examples that demonstrate different methods for comparing multiple array elements:
3.1. Comparing Adjacent Elements Using a Loop
This example compares adjacent elements in an array and outputs the larger of each pair:
module compare_adjacent (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] result_array [0:3]
);
integer i;
always @(posedge clk) begin
if (rst) begin
for (i = 0; i < 4; i = i + 1) begin
result_array[i] <= 0;
end
end else begin
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
result_array[i] <= data_array[2*i];
end else begin
result_array[i] <= data_array[2*i+1];
end
end
end
end
endmodule
In this example, the compare_adjacent
module compares adjacent elements in the data_array
and stores the larger value in the result_array
.
3.2. Comparing All Elements to a Threshold Value Using a Loop
This example compares each element in an array to a threshold value and outputs a flag indicating whether any element is greater than the threshold:
module compare_threshold (
input clk,
input rst,
input [7:0] data_array [0:7],
input [7:0] threshold,
output reg any_greater
);
integer i;
always @(posedge clk) begin
if (rst) begin
any_greater <= 0;
end else begin
any_greater <= 0; // Initialize to 0
for (i = 0; i < 8; i = i + 1) begin
if (data_array[i] > threshold) begin
any_greater <= 1;
end
end
end
end
endmodule
Here, the compare_threshold
module compares each element in the data_array
to the threshold
value. If any element is greater than the threshold, the any_greater
flag is set to 1.
3.3. Finding the Maximum Value in an Array Using a Loop
This example finds the maximum value in an array using a loop:
module find_maximum (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
max_value <= data_array[0]; // Initialize with the first element
for (i = 1; i < 8; i = i + 1) begin
if (data_array[i] > max_value) begin
max_value <= data_array[i];
end
end
end
end
endmodule
In this example, the find_maximum
module iterates through the data_array
, comparing each element to the current max_value
. If an element is larger than max_value
, it updates max_value
accordingly.
3.4. Parallel Comparison of Array Elements Using Generate Statements
This example compares array elements in parallel using generate statements to find the maximum value:
module parallel_maximum (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
wire [7:0] compare_tree [0:3];
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
// First level of comparison
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
compare_tree[i] <= data_array[2*i];
end else begin
compare_tree[i] <= data_array[2*i+1];
end
end
// Second level of comparison
for (i = 0; i < 2; i = i + 1) begin
if (compare_tree[2*i] > compare_tree[2*i+1]) begin
compare_tree[i+4] <= compare_tree[2*i];
end else begin
compare_tree[i+4] <= compare_tree[2*i+1];
end
end
// Final comparison
if (compare_tree[4] > compare_tree[5]) begin
max_value <= compare_tree[4];
end else begin
max_value <= compare_tree[5];
end
end
end
endmodule
This example demonstrates how generate statements can be used to create a parallel comparison structure, reducing the latency of finding the maximum value.
4. Optimizing Array Comparison for Performance
How can array comparison be optimized in Verilog for better performance? Optimizing array comparison in Verilog involves reducing comparison latency and minimizing resource utilization. Techniques such as pipelining, parallel processing, sharing comparators, and using efficient data structures can be employed to achieve these goals.
4.1. Reducing Comparison Latency
How can latency be reduced when comparing multiple array elements in Verilog? Reducing comparison latency is crucial for high-performance designs. Pipelining and parallel processing are two effective techniques for achieving this.
4.1.1. Pipelining
Pipelining involves breaking down the comparison process into multiple stages and executing each stage in parallel. This allows you to process multiple sets of data concurrently, reducing the overall latency.
Example:
module pipelined_maximum (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
reg [7:0] stage1 [0:3];
reg [7:0] stage2 [0:1];
reg [7:0] stage3 [0:0];
integer i;
always @(posedge clk) begin
if (rst) begin
// Initialize pipeline stages
for (i = 0; i < 4; i = i + 1) begin
stage1[i] <= 0;
end
for (i = 0; i < 2; i = i + 1) begin
stage2[i] <= 0;
end
for (i = 0; i < 1; i = i + 1) begin
stage3[i] <= 0;
end
max_value <= 0;
end else begin
// Stage 1: Compare adjacent pairs
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
stage1[i] <= data_array[2*i];
end else begin
stage1[i] <= data_array[2*i+1];
end
end
// Stage 2: Compare pairs from stage 1
for (i = 0; i < 2; i = i + 1) begin
if (stage1[2*i] > stage1[2*i+1]) begin
stage2[i] <= stage1[2*i];
end else begin
stage2[i] <= stage1[2*i+1];
end
end
// Stage 3: Compare pairs from stage 2
if (stage2[0] > stage2[1]) begin
stage3[0] <= stage2[0];
end else begin
stage3[0] <= stage2[1];
end
// Final stage: Output the maximum value
max_value <= stage3[0];
end
end
endmodule
In this example, the pipelined_maximum
module breaks down the comparison process into three stages, allowing for concurrent processing of data.
4.1.2. Parallel Processing
Parallel processing involves using multiple comparators to compare array elements simultaneously. This can be achieved using generate statements or by instantiating multiple comparator modules.
Example:
module parallel_maximum (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
wire [7:0] compare_tree [0:3];
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
// First level of comparison
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
compare_tree[i] <= data_array[2*i];
end else begin
compare_tree[i] <= data_array[2*i+1];
end
end
// Second level of comparison
for (i = 0; i < 2; i = i + 1) begin
if (compare_tree[2*i] > compare_tree[2*i+1]) begin
compare_tree[i+4] <= compare_tree[2*i];
end else begin
compare_tree[i+4] <= compare_tree[2*i+1];
end
end
// Final comparison
if (compare_tree[4] > compare_tree[5]) begin
max_value <= compare_tree[4];
end else begin
max_value <= compare_tree[5];
end
end
end
endmodule
This example demonstrates how parallel processing can be used to reduce the comparison latency.
4.2. Minimizing Resource Utilization
How can resource utilization be minimized when comparing multiple array elements in Verilog? Minimizing resource utilization is important for reducing the area and power consumption of your design. Sharing comparators and using efficient data structures are two effective techniques for achieving this.
4.2.1. Sharing Comparators
Sharing comparators involves reusing the same comparator for multiple comparisons. This can be achieved by multiplexing the inputs to the comparator.
Example:
module shared_comparator (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
reg [2:0] index;
reg [7:0] current_max;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
index <= 0;
current_max <= 0;
end else begin
case (index)
0: current_max <= data_array[0];
default: if (data_array[index] > current_max) begin
current_max <= data_array[index];
end
endcase
if (index == 7) begin
max_value <= current_max;
index <= 0;
end else begin
index <= index + 1;
end
end
end
endmodule
In this example, the shared_comparator
module reuses the same comparator for each comparison, reducing the overall resource utilization.
4.2.2. Using Efficient Data Structures
Using efficient data structures can also help minimize resource utilization. For example, using a binary tree structure can reduce the number of comparators needed to find the maximum value.
4.3. Balancing Latency and Resource Utilization
How to effectively balance latency and resource utilization when comparing arrays? Balancing latency and resource utilization involves choosing the right combination of techniques to meet your design requirements. Pipelining and parallel processing can reduce latency but increase resource utilization, while sharing comparators and using efficient data structures can reduce resource utilization but increase latency.
The optimal balance depends on the specific requirements of your design and the available resources.
5. Case Studies and Practical Applications
In what real-world applications is array comparison used in Verilog? Array comparison is a fundamental operation in many digital systems. Here are some case studies and practical applications where array comparison is commonly used:
5.1. Image Processing
Image processing algorithms often involve comparing pixel values to perform tasks such as edge detection, noise reduction, and image enhancement. For example, comparing the intensity values of neighboring pixels can help identify edges in an image.
5.2. Digital Signal Processing (DSP)
DSP applications often involve comparing signal samples to perform tasks such as filtering, modulation, and demodulation. For example, comparing the amplitude of a signal to a threshold can help detect the presence of a specific event.
5.3. Network Packet Processing
Network packet processing involves comparing packet headers to determine the destination and priority of the packet. For example, comparing the destination IP address in a packet header to a routing table can help determine the next hop for the packet.
6. Simulation and Verification
What are the key steps in simulating and verifying array comparison logic in Verilog? Simulation and verification are essential steps in the digital design process to ensure that your array comparison logic works correctly. This section discusses how to write testbenches, use assertions, and debug array comparison logic.
6.1. Writing Testbenches for Array Comparison
A testbench is a Verilog module that provides inputs to your design and checks the outputs against expected values. A well-written testbench is crucial for verifying the correctness of your array comparison logic.
Example:
module testbench;
reg clk;
reg rst;
reg [7:0] data_array [0:7];
wire [7:0] max_value;
parallel_maximum dut (
.clk(clk),
.rst(rst),
.data_array(data_array),
.max_value(max_value)
);
// Clock generation
always #5 clk = ~clk;
initial begin
// Initialize signals
clk = 0;
rst = 1;
// Apply reset
#10 rst = 0;
// Initialize data array
data_array[0] = 10;
data_array[1] = 20;
data_array[2] = 15;
data_array[3] = 25;
data_array[4] = 5;
data_array[5] = 30;
data_array[6] = 22;
data_array[7] = 18;
// Wait for some time
#100;
// Display the maximum value
$display("Maximum value: %d", max_value);
// End simulation
$finish;
end
endmodule
This example shows a simple testbench for the parallel_maximum
module. The testbench provides a clock and reset signal, initializes the data array, and checks the output max_value
.
6.2. Using Assertions for Verification
Assertions are statements that check whether a specific condition is true during simulation. If the condition is false, the assertion will fail, indicating a potential problem in your design.
Example:
module parallel_maximum (
input clk,
input rst,
input [7:0] data_array [0:7],
output reg [7:0] max_value
);
wire [7:0] compare_tree [0:3];
integer i;
always @(posedge clk) begin
if (rst) begin
max_value <= 0;
end else begin
// First level of comparison
for (i = 0; i < 4; i = i + 1) begin
if (data_array[2*i] > data_array[2*i+1]) begin
compare_tree[i] <= data_array[2*i];
end else begin
compare_tree[i] <= data_array[2*i+1];
end
end
// Second level of comparison
for (i = 0; i < 2; i = i + 1) begin
if (compare_tree[2*i] > compare_tree[2*i+1]) begin
compare_tree[i+4] <= compare_tree[2*i];
end