Control flow statements in SystemVerilog allow you to control the execution path of your code based on conditions and loops. This chapter covers all essential control structures used in both synthesizable RTL design and testbench development.
if-else Statements
The if-else statement is the most fundamental conditional control structure in SystemVerilog.
Basic Syntax
if (condition1) begin// statementsendelseif (condition2) begin// statementsendelsebegin// statementsend
Single Statement (without begin-end)
if (condition) statement;else statement;
Practical Examples
Example 1: Simple Comparator
// comparator.svmodule comparator(inputlogic [7:0] a, b,outputlogic gt, eq, lt);always_combbeginif (a > b) begin gt = 1'b1;eq = 1'b0; lt = 1'b0;endelseif (a == b) begin gt = 1'b0;eq = 1'b1; lt = 1'b0;endelsebegin gt = 1'b0;eq = 1'b0; lt = 1'b1;endendendmodule
// comparator_testbench.svmodule comparator_testbench; // Testbench module// Testbench signalslogic [7:0] a, b;logic gt, eq, lt;// Instantiate design under test comparator DUT ( .a(a), .b(b), .gt(gt), .eq(eq), .lt(lt) );initialbegin// Dump waves$dumpfile("comparator_testbench.vcd"); // Specify the VCD file$dumpvars(0, comparator_testbench); // Dump all variables in the test module$display();$display("Starting Comparator Tests");$display("====================");$display();// Test case 1: a > b a = 8'h50; b = 8'h30;#1; // Wait for combinational logic to settle$display("Test 1: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b1 && eq == 1'b0 && lt == 1'b0) else$error("Test 1 failed: Expected gt=1, eq=0, lt=0");// Test case 2: a == b a = 8'h42; b = 8'h42;#1;$display("Test 2: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b0 && eq == 1'b1 && lt == 1'b0) else$error("Test 2 failed: Expected gt=0, eq=1, lt=0");// Test case 3: a < b a = 8'h10; b = 8'h60;#1;$display("Test 3: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b0 && eq == 1'b0 && lt == 1'b1) else$error("Test 3 failed: Expected gt=0, eq=0, lt=1");// Test case 4: Edge case - maximum values a = 8'hFF; b = 8'hFF;#1;$display("Test 4: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b0 && eq == 1'b1 && lt == 1'b0) else$error("Test 4 failed: Expected gt=0, eq=1, lt=0");// Test case 5: Edge case - minimum values a = 8'h00; b = 8'h00;#1;$display("Test 5: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b0 && eq == 1'b1 && lt == 1'b0) else$error("Test 5 failed: Expected gt=0, eq=1, lt=0");// Test case 6: One maximum, one minimum a = 8'hFF; b = 8'h00;#1;$display("Test 6: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b1 && eq == 1'b0 && lt == 1'b0) else$error("Test 6 failed: Expected gt=1, eq=0, lt=0");// Test case 7: One minimum, one maximum a = 8'h00; b = 8'hFF;#1;$display("Test 7: a=%0d, b=%0d -> gt=%b, eq=%b, lt=%b", a, b, gt, eq, lt);assert (gt == 1'b0 && eq == 1'b0 && lt == 1'b1) else$error("Test 7 failed: Expected gt=0, eq=0, lt=1");$display();$display("All tests completed!");$display("====================");$display();$finish; // End simulationendendmodule
Verilator Simulation Output:
================================================================================
Starting Comparator Tests
====================
Test 1: a=80, b=48 -> gt=1, eq=0, lt=0
Test 2: a=66, b=66 -> gt=0, eq=1, lt=0
Test 3: a=16, b=96 -> gt=0, eq=0, lt=1
Test 4: a=255, b=255 -> gt=0, eq=1, lt=0
Test 5: a=0, b=0 -> gt=0, eq=1, lt=0
Test 6: a=255, b=0 -> gt=1, eq=0, lt=0
Test 7: a=0, b=255 -> gt=0, eq=0, lt=1
All tests completed!
====================
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_1__comparator/obj_dir directory...
Chapter_4_examples/example_1__comparator/obj_dir removed successfully.
// priority_encoder_testbench.svmodule priority_encoder_testbench; // Testbench module// Testbench signalslogic [7:0] data_in;logic [2:0] encoded_out;logic valid;// Test counterinteger test_count = 0;integer pass_count = 0;// Instantiate design under test priority_encoder DUT ( .data_in(data_in), .encoded_out(encoded_out), .valid(valid) );// Task to run a test casetask run_test(input [7:0] test_data,input [2:0] expected_out,input expected_valid,inputstring test_name ); test_count++; data_in = test_data;#1; // Wait for combinational logic to settle$display("Test %0d: %s", test_count, test_name);$display(" Input: 8'b%08b (0x%02h)", data_in, data_in);$display(" Output: encoded_out=%0d, valid=%b", encoded_out, valid);$display(" Expected: encoded_out=%0d, valid=%b", expected_out, expected_valid);if (encoded_out == expected_out && valid == expected_valid) begin$display("PASS"); pass_count++;endelsebegin$display("FAIL");$error("Test %0d failed: Expected encoded_out=%0d, valid=%b, got encoded_out=%0d, valid=%b", test_count, expected_out, expected_valid, encoded_out, valid);end$display();endtaskinitialbegin// Dump waves$dumpfile("priority_encoder_testbench.vcd"); // Specify the VCD file$dumpvars(0, priority_encoder_testbench); // Dump all variables in the test module$display();$display("Hello from testbench!");$display("Starting Priority Encoder Tests");$display("==============================");$display();$display("Priority Encoder: Encodes the position of the highest priority (MSB) active bit");$display("- 8-bit input, 3-bit encoded output");$display("- Bit 7 has highest priority, Bit 0 has lowest priority");$display("- Valid output indicates if any input bit is active");$display();// Test 1: No input (all zeros) run_test(8'b00000000, 3'd0, 1'b0, "All zeros - no valid input");// Test 2: Single bit tests (one bit at a time) run_test(8'b00000001, 3'd0, 1'b1, "Only bit 0 active"); run_test(8'b00000010, 3'd1, 1'b1, "Only bit 1 active"); run_test(8'b00000100, 3'd2, 1'b1, "Only bit 2 active"); run_test(8'b00001000, 3'd3, 1'b1, "Only bit 3 active"); run_test(8'b00010000, 3'd4, 1'b1, "Only bit 4 active"); run_test(8'b00100000, 3'd5, 1'b1, "Only bit 5 active"); run_test(8'b01000000, 3'd6, 1'b1, "Only bit 6 active"); run_test(8'b10000000, 3'd7, 1'b1, "Only bit 7 active (highest priority)");// Test 3: Multiple bits - priority should go to highest bit run_test(8'b10000001, 3'd7, 1'b1, "Bits 7 and 0 - priority to bit 7"); run_test(8'b01000010, 3'd6, 1'b1, "Bits 6 and 1 - priority to bit 6"); run_test(8'b00100100, 3'd5, 1'b1, "Bits 5 and 2 - priority to bit 5"); run_test(8'b00011000, 3'd4, 1'b1, "Bits 4 and 3 - priority to bit 4");// Test 4: Sequential patterns run_test(8'b11111111, 3'd7, 1'b1, "All bits set - priority to bit 7"); run_test(8'b01111111, 3'd6, 1'b1, "Bits 6-0 set - priority to bit 6"); run_test(8'b00111111, 3'd5, 1'b1, "Bits 5-0 set - priority to bit 5"); run_test(8'b00011111, 3'd4, 1'b1, "Bits 4-0 set - priority to bit 4"); run_test(8'b00001111, 3'd3, 1'b1, "Bits 3-0 set - priority to bit 3"); run_test(8'b00000111, 3'd2, 1'b1, "Bits 2-0 set - priority to bit 2"); run_test(8'b00000011, 3'd1, 1'b1, "Bits 1-0 set - priority to bit 1");// Test 5: Random patterns to verify priority run_test(8'b10101010, 3'd7, 1'b1, "Alternating pattern starting with bit 7"); run_test(8'b01010101, 3'd6, 1'b1, "Alternating pattern starting with bit 6"); run_test(8'b00110011, 3'd5, 1'b1, "Pattern 00110011 - priority to bit 5"); run_test(8'b00001100, 3'd3, 1'b1, "Pattern 00001100 - priority to bit 3");// Test 6: Edge cases run_test(8'b11000000, 3'd7, 1'b1, "Only upper bits (7,6) - priority to bit 7"); run_test(8'b00000011, 3'd1, 1'b1, "Only lower bits (1,0) - priority to bit 1");// Summary$display("Test Summary:");$display("============");$display("Total tests: %0d", test_count);$display("Passed: %0d", pass_count);$display("Failed: %0d", test_count - pass_count);if (pass_count == test_count) begin$display("ALL TESTS PASSED!");endelsebegin$display("Some tests failed. Please review.");end$display();$display("Priority Encoder Testing Complete!");$display("=================================");$display();$finish; // End simulationendendmodule
Verilator Simulation Output:
================================================================================
Hello from testbench!
Starting Priority Encoder Tests
==============================
Priority Encoder: Encodes the position of the highest priority (MSB) active bit
- 8-bit input, 3-bit encoded output
- Bit 7 has highest priority, Bit 0 has lowest priority
- Valid output indicates if any input bit is active
Test 1: All zeros - no valid input
Input: 8'b00000000 (0x00)
Output: encoded_out=0, valid=0
Expected: encoded_out=0, valid=0
PASS
Test 2: Only bit 0 active
Input: 8'b00000001 (0x01)
Output: encoded_out=0, valid=1
Expected: encoded_out=0, valid=1
PASS
Test 3: Only bit 1 active
Input: 8'b00000010 (0x02)
Output: encoded_out=1, valid=1
Expected: encoded_out=1, valid=1
PASS
Test 4: Only bit 2 active
Input: 8'b00000100 (0x04)
Output: encoded_out=2, valid=1
Expected: encoded_out=2, valid=1
PASS
Test 5: Only bit 3 active
Input: 8'b00001000 (0x08)
Output: encoded_out=3, valid=1
Expected: encoded_out=3, valid=1
PASS
Test 6: Only bit 4 active
Input: 8'b00010000 (0x10)
Output: encoded_out=4, valid=1
Expected: encoded_out=4, valid=1
PASS
Test 7: Only bit 5 active
Input: 8'b00100000 (0x20)
Output: encoded_out=5, valid=1
Expected: encoded_out=5, valid=1
PASS
Test 8: Only bit 6 active
Input: 8'b01000000 (0x40)
Output: encoded_out=6, valid=1
Expected: encoded_out=6, valid=1
PASS
Test 9: Only bit 7 active (highest priority)
Input: 8'b10000000 (0x80)
Output: encoded_out=7, valid=1
Expected: encoded_out=7, valid=1
PASS
Test 10: Bits 7 and 0 - priority to bit 7
Input: 8'b10000001 (0x81)
Output: encoded_out=7, valid=1
Expected: encoded_out=7, valid=1
PASS
Test 11: Bits 6 and 1 - priority to bit 6
Input: 8'b01000010 (0x42)
Output: encoded_out=6, valid=1
Expected: encoded_out=6, valid=1
PASS
Test 12: Bits 5 and 2 - priority to bit 5
Input: 8'b00100100 (0x24)
Output: encoded_out=5, valid=1
Expected: encoded_out=5, valid=1
PASS
Test 13: Bits 4 and 3 - priority to bit 4
Input: 8'b00011000 (0x18)
Output: encoded_out=4, valid=1
Expected: encoded_out=4, valid=1
PASS
Test 14: All bits set - priority to bit 7
Input: 8'b11111111 (0xff)
Output: encoded_out=7, valid=1
Expected: encoded_out=7, valid=1
PASS
Test 15: Bits 6-0 set - priority to bit 6
Input: 8'b01111111 (0x7f)
Output: encoded_out=6, valid=1
Expected: encoded_out=6, valid=1
PASS
Test 16: Bits 5-0 set - priority to bit 5
Input: 8'b00111111 (0x3f)
Output: encoded_out=5, valid=1
Expected: encoded_out=5, valid=1
PASS
Test 17: Bits 4-0 set - priority to bit 4
Input: 8'b00011111 (0x1f)
Output: encoded_out=4, valid=1
Expected: encoded_out=4, valid=1
PASS
Test 18: Bits 3-0 set - priority to bit 3
Input: 8'b00001111 (0x0f)
Output: encoded_out=3, valid=1
Expected: encoded_out=3, valid=1
PASS
Test 19: Bits 2-0 set - priority to bit 2
Input: 8'b00000111 (0x07)
Output: encoded_out=2, valid=1
Expected: encoded_out=2, valid=1
PASS
Test 20: Bits 1-0 set - priority to bit 1
Input: 8'b00000011 (0x03)
Output: encoded_out=1, valid=1
Expected: encoded_out=1, valid=1
PASS
Test 21: Alternating pattern starting with bit 7
Input: 8'b10101010 (0xaa)
Output: encoded_out=7, valid=1
Expected: encoded_out=7, valid=1
PASS
Test 22: Alternating pattern starting with bit 6
Input: 8'b01010101 (0x55)
Output: encoded_out=6, valid=1
Expected: encoded_out=6, valid=1
PASS
Test 23: Pattern 00110011 - priority to bit 5
Input: 8'b00110011 (0x33)
Output: encoded_out=5, valid=1
Expected: encoded_out=5, valid=1
PASS
Test 24: Pattern 00001100 - priority to bit 3
Input: 8'b00001100 (0x0c)
Output: encoded_out=3, valid=1
Expected: encoded_out=3, valid=1
PASS
Test 25: Only upper bits (7,6) - priority to bit 7
Input: 8'b11000000 (0xc0)
Output: encoded_out=7, valid=1
Expected: encoded_out=7, valid=1
PASS
Test 26: Only lower bits (1,0) - priority to bit 1
Input: 8'b00000011 (0x03)
Output: encoded_out=1, valid=1
Expected: encoded_out=1, valid=1
PASS
Test Summary:
============
Total tests: 26
Passed: 26
Failed: 0
ALL TESTS PASSED!
Priority Encoder Testing Complete!
=================================
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_2__priority_encoder/obj_dir directory...
Chapter_4_examples/example_2__priority_encoder/obj_dir removed successfully.
0
Best Practices for if-else
Always use begin-end blocks for multiple statements
Use always_comb for combinational logic
Use always_ff for sequential logic
Avoid complex nested conditions when possible
Case Statements
Case statements provide a cleaner alternative to multiple if-else statements when comparing a single expression against multiple values.
case Statement
The standard case statement performs exact matching including X and Z values.
// alu.svmodule alu(inputlogic [3:0] opcode,inputlogic [7:0] a, b,outputlogic [7:0] result,outputlogic zero);always_combbegincase (opcode)4'b0000: result = a + b; // ADD4'b0001: result = a - b; // SUB4'b0010: result = a & b; // AND4'b0011: result = a | b; // OR4'b0100: result = a ^ b; // XOR4'b0101: result = ~a; // NOT4'b0110: result = a << 1; // Shift left4'b0111: result = a >> 1; // Shift rightdefault: result = 8'h00;endcase zero = (result == 8'h00);endendmodule
casex treats X and Z as don’t-care values in both the case expression and case items.
casex (data)4'b1???: // Matches any 4-bit value starting with 1 result = "starts_with_1";4'b?1??: // Matches any 4-bit value with second bit as 1 result = "second_bit_1";default: result = "other";endcase
// counter_4bit_testbench.svmodule counter_4bit_testbench;logic clk, rst_n, enable;logic [3:0] count;integer test_cycles;// Instantiate the 4-bit counter design under test counter_4bit dut_counter ( .clk(clk), .rst_n(rst_n), .enable(enable), .count(count) );// Clock generation - 10ns period (100MHz)initialbegin clk = 0;forever#5 clk = ~clk;end// Main test sequenceinitialbegin// Setup waveform dumping$dumpfile("counter_4bit_testbench.vcd");$dumpvars(0, counter_4bit_testbench);// Initialize test signals rst_n = 0; enable = 0; test_cycles = 0;$display("=== 4-bit Counter Testbench Started ===");$display("Time: %0t", $time);$display();// Apply reset for 10ns#10 rst_n = 1;$display("Reset deasserted at time %0t", $time);// Enable counting after reset#10 enable = 1;$display("Counter enabled at time %0t", $time);$display();// Run test for 20 clock cycleswhile (test_cycles < 20) begin @(posedge clk);$display("Cycle %2d: count = %2d (0x%h) at time %0t", test_cycles, count, count, $time); test_cycles++;// Test disable functionality at cycle 10if (test_cycles == 10) begin enable = 0;$display(">>> Counter disabled at cycle %0d <<<", test_cycles);end// Re-enable at cycle 15if (test_cycles == 15) begin enable = 1;$display(">>> Counter re-enabled at cycle %0d <<<", test_cycles);endend$display();$display("=== Testbench Completed Successfully ===");$display("Final count value: %0d", count);$display("Total simulation time: %0t", $time);$finish;end// Overflow detection monitoralways @(posedge clk) beginif (rst_n && enable && count == 4'b1111) begin$display("*** OVERFLOW WARNING: Counter reached maximum value (15) ***");endend// Value change monitor for debuggingalways @(count) beginif (rst_n) begin$display("Count changed to: %0d", count);endendendmodule
Verilator Simulation Output:
================================================================================
=== 4-bit Counter Testbench Started ===
Time: 0
Counter reset - count = 0
Reset deasserted at time 10
Counter disabled - count = 0
Counter enabled at time 20
Cycle 0: count = 0 (0x0) at time 25
Counter enabled - count = 1
Count changed to: 1
Cycle 1: count = 1 (0x1) at time 35
Counter enabled - count = 2
Count changed to: 2
Cycle 2: count = 2 (0x2) at time 45
Counter enabled - count = 3
Count changed to: 3
Cycle 3: count = 3 (0x3) at time 55
Counter enabled - count = 4
Count changed to: 4
Cycle 4: count = 4 (0x4) at time 65
Counter enabled - count = 5
Count changed to: 5
Cycle 5: count = 5 (0x5) at time 75
Counter enabled - count = 6
Count changed to: 6
Cycle 6: count = 6 (0x6) at time 85
Counter enabled - count = 7
Count changed to: 7
Cycle 7: count = 7 (0x7) at time 95
Counter enabled - count = 8
Count changed to: 8
Cycle 8: count = 8 (0x8) at time 105
Counter enabled - count = 9
Count changed to: 9
Cycle 9: count = 9 (0x9) at time 115
>>> Counter disabled at cycle 10 <<<
Counter disabled - count = 9
Cycle 10: count = 9 (0x9) at time 125
Counter disabled - count = 9
Cycle 11: count = 9 (0x9) at time 135
Counter disabled - count = 9
Cycle 12: count = 9 (0x9) at time 145
Counter disabled - count = 9
Cycle 13: count = 9 (0x9) at time 155
Counter disabled - count = 9
Cycle 14: count = 9 (0x9) at time 165
>>> Counter re-enabled at cycle 15 <<<
Counter enabled - count = 10
Count changed to: 10
Cycle 15: count = 10 (0xa) at time 175
Counter enabled - count = 11
Count changed to: 11
Cycle 16: count = 11 (0xb) at time 185
Counter enabled - count = 12
Count changed to: 12
Cycle 17: count = 12 (0xc) at time 195
Counter enabled - count = 13
Count changed to: 13
Cycle 18: count = 13 (0xd) at time 205
Counter enabled - count = 14
Count changed to: 14
Cycle 19: count = 14 (0xe) at time 215
=== Testbench Completed Successfully ===
Final count value: 14
Total simulation time: 215
- counter_4bit_testbench.sv:69: Verilog $finish
Counter enabled - count = 15
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_8__counter_4bit/obj_dir directory...
Chapter_4_examples/example_8__counter_4bit/obj_dir removed successfully.
0
do-while Loop
The do-while loop executes at least once before checking the condition.
dobegin// statementsendwhile (condition);
Example 9: Random Test Generation
// unique_random_generator.svmodule unique_random_generator (); // Design under test// Test class that generates unique consecutive random valuesclass random_test;randbit [7:0] data;bit [7:0] prev_value;// Function to generate values different from previous onefunctionvoid generate_unique_values();int success;dobegin success = randomize();if (success == 0) begin$error("Randomization failed!");break;endendwhile (data == prev_value); prev_value = data;endfunctionendclass// Design logic with random test functionalityinitialbegin random_test rnd_gen;bit [7:0] value_history[5];$display(); // Display empty line$display("Hello from design!"); // Display message$display("=== Unique Random Value Generation ===");// Create instance of random test class rnd_gen = new();// Generate and display 5 unique consecutive valuesfor (int i = 0; i < 5; i++) begin rnd_gen.generate_unique_values(); value_history[i] = rnd_gen.data;$display("Generation %0d: Value=0x%02h, Previous=0x%02h", i+1, rnd_gen.data, rnd_gen.prev_value);end$display("Design random generation completed!");endendmodule
// unique_random_generator_testbench.svmodule unique_random_generator_testbench; // Testbench module unique_random_generator UNIQUE_RANDOM_GENERATOR(); // Instantiate design under test// Additional testbench-specific random testingclass random_test;randbit [7:0] data;bit [7:0] prev_value;functionvoid generate_unique_values();int success;dobegin success = randomize();if (success == 0) begin$error("Randomization failed!");break;endendwhile (data == prev_value); prev_value = data;endfunctionendclassinitialbegin random_test tb_rnd_gen;// Dump waves$dumpfile("unique_random_generator_testbench.vcd"); // Specify the VCD file$dumpvars(0, unique_random_generator_testbench); // Dump all variables in the test module#1; // Wait for a time unit$display("Hello from testbench!"); // Display message$display(); // Display empty line// Testbench-specific random value testing$display("=== Testbench Random Value Verification ==="); tb_rnd_gen = new();// Test multiple generations to verify uniquenessfor (int i = 0; i < 8; i++) begin tb_rnd_gen.generate_unique_values();$display("TB Test %0d: Generated=0x%02h, Previous=0x%02h, Unique=%s", i+1, tb_rnd_gen.data, tb_rnd_gen.prev_value, (i == 0) ? "N/A" : "YES");#5; // Small delay between generationsend$display("Testbench verification completed!");#10;$finish;endendmodule
Verilator Simulation Output:
================================================================================
- Verilator: Walltime 32.008 s (elab=0.003, cvt=0.094, bld=30.907); cpu 0.066 s
on 1 threads; alloced 20.176 MB
Hello from design!
=== Unique Random Value Generation ===
Generation 1: Value=0xc4, Previous=0xc4
Generation 2: Value=0x9c, Previous=0x9c
Generation 3: Value=0x02, Previous=0x02
Generation 4: Value=0xe4, Previous=0xe4
Generation 5: Value=0x78, Previous=0x78
Design random generation completed!
Hello from testbench!
=== Testbench Random Value Verification ===
TB Test 1: Generated=0x9c, Previous=0x9c, Unique=N/A
TB Test 2: Generated=0x02, Previous=0x02, Unique=YES
TB Test 3: Generated=0xe4, Previous=0xe4, Unique=YES
TB Test 4: Generated=0x78, Previous=0x78, Unique=YES
TB Test 5: Generated=0xbc, Previous=0xbc, Unique=YES
TB Test 6: Generated=0xb6, Previous=0xb6, Unique=YES
TB Test 7: Generated=0xe4, Previous=0xe4, Unique=YES
TB Test 8: Generated=0xb7, Previous=0xb7, Unique=YES
Testbench verification completed!
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_9__unique_random_generator/obj_dir directory...
Chapter_4_examples/example_9__unique_random_generator/obj_dir removed successfully.
0
foreach Loops
The foreach loop iterates over arrays, providing a clean syntax for array operations.
foreach (array_name[i]) begin// statements using array_name[i]end
Example 10: Array Processing
// array_processor.svmodule array_processor (); // Design under test// Array processing class with various operationsclass array_operations;logic [7:0] data_array[16];logic [15:0] sum; // Fixed: Increased to 16-bit to prevent overflowlogic [7:0] avg;logic [7:0] min_val;logic [7:0] max_val;integer array_size;functionnew(); array_size = 16; initialize_array();endfunction// Function to initialize array with patternfunctionvoid initialize_array();foreach (data_array[i]) begin data_array[i] = 8'(i * 2 + 1); // Odd numbers: 1, 3, 5, 7, ...endendfunction// Function to calculate sum of array elementsfunctionvoid calculate_sum();sum = 16'h0000;foreach (data_array[i]) beginsum = sum + 16'(data_array[i]); // Fixed: Explicit cast and assignment to avoid width warningsendendfunction// Function to calculate averagefunctionvoid calculate_average(); calculate_sum(); avg = 8'(sum / array_size); // Fixed: Now uses correct sum valueendfunction// Function to find minimum and maximum valuesfunctionvoid find_min_max(); min_val = data_array[0]; max_val = data_array[0];foreach (data_array[i]) beginif (data_array[i] < min_val) min_val = data_array[i];if (data_array[i] > max_val) max_val = data_array[i];endendfunction// Function to display array contentsfunctionvoid display_array();$display("Array contents:");foreach (data_array[i]) begin$display(" data_array[%0d] = %0d (0x%02h)", i, data_array[i], data_array[i]);endendfunction// Function to display statisticsfunctionvoid display_statistics();$display("Array Statistics:");$display(" Size: %0d elements", array_size);$display(" Sum: %0d", sum);$display(" Avg: %0d", avg);$display(" Min: %0d", min_val);$display(" Max: %0d", max_val);endfunctionendclass// Design logic with array processing functionalityinitialbegin array_operations arr_proc;$display(); // Display empty line$display("Hello from design!"); // Display message$display("=== Array Processing Operations ===");// Create instance of array operations class arr_proc = new();// Display initial array arr_proc.display_array();$display();// Perform array operations arr_proc.calculate_sum(); arr_proc.calculate_average(); arr_proc.find_min_max();// Display results arr_proc.display_statistics();$display("Design array processing completed!");endendmodule
// array_processor_testbench.svmodule array_processor_testbench; // Testbench module array_processor ARRAY_PROCESSOR(); // Instantiate design under test// Extended testbench class for additional array testingclass array_test;logic [7:0] test_array[16];logic [15:0] expected_sum; // Fixed: Increased to 16-bit to prevent overflowlogic [15:0] actual_sum; // Fixed: Increased to 16-bit to prevent overflowinteger test_size;functionnew(); test_size = 16;endfunction// Function to initialize test array with different patternfunctionvoid initialize_test_array();foreach (test_array[i]) begin// Fixed: Proper casting and clearer logicif (i % 2 == 0) begin test_array[i] = 8'(i * 3); // Even indices: 0, 6, 12, 18, ...endelsebegin test_array[i] = 8'(i + 10); // Odd indices: 11, 12, 13, 14, ...endendendfunction// Function to calculate expected sumfunctionvoid calculate_expected_sum(); expected_sum = 16'h0000;foreach (test_array[i]) begin expected_sum = expected_sum + 16'(test_array[i]); // Fixed: Explicit cast and assignmentendendfunction// Function to verify array operationsfunctionbit verify_sum(); actual_sum = 16'h0000;foreach (test_array[i]) begin actual_sum = actual_sum + 16'(test_array[i]); // Fixed: Explicit cast and assignmentendreturn (actual_sum == expected_sum);endfunction// Function to display test arrayfunctionvoid display_test_array();$display("Test Array Pattern:");foreach (test_array[i]) begin$display(" test_array[%0d] = %0d (0x%02h)", i, test_array[i], test_array[i]);endendfunction// Function to run verificationfunctionvoid run_verification();bit sum_check;// Array is already initialized, just calculate and verify calculate_expected_sum(); sum_check = verify_sum();$display("=== Verification Results ===");$display("Expected Sum: %0d", expected_sum);$display("Actual Sum: %0d", actual_sum);$display("Sum Check: %s", sum_check ? "PASS" : "FAIL");if (sum_check) begin$display("Array sum verification PASSED");endelsebegin$display("Array sum verification FAILED");endendfunctionendclassinitialbegin array_test tb_arr_test;// Dump waves$dumpfile("array_processor_testbench.vcd"); // Specify the VCD file$dumpvars(0, array_processor_testbench); // Dump all variables in the test module#10; // Wait for 10 time units$display("Hello from testbench!"); // Display message$display(); // Display empty line// Testbench-specific array testing$display("=== Testbench Array Verification ==="); tb_arr_test = new();// Initialize test array first, then display tb_arr_test.initialize_test_array(); tb_arr_test.display_test_array();$display();// Run verification tests tb_arr_test.run_verification();$display();$display("=== Additional Array Tests ===");// Test with different array sizes conceptuallyfor (int test_case = 1; test_case <= 3; test_case++) begin$display("Test Case %0d: Running array operations...", test_case);// Simulate different processing scenarioscase (test_case)1: $display(" Processing sequential data pattern");2: $display(" Processing alternating data pattern"); 3: $display(" Processing random-like data pattern");endcase#5; // Small delay between test casesend$display("Testbench verification completed!");#10;$display();$finish;endendmodule
// matrix_processor.svmodule matrix_processor (); // Matrix operations design under testlogic [7:0] matrix[4][4];logic [7:0] row_sum[4];initialbegin$display();$display("Matrix Processor: Starting operations...");// Initialize matrixforeach (matrix[i]) beginforeach (matrix[i][j]) begin matrix[i][j] = 8'(i + j);endend// Calculate row sumsforeach (row_sum[i]) begin row_sum[i] = 0;foreach (matrix[i][j]) begin row_sum[i] += matrix[i][j];endend// Display results$display("Matrix values and row sums:");foreach (row_sum[i]) begin$display("Row %0d sum = %0d", i, row_sum[i]);end$display("Matrix Processor: Operations completed.");endendmodule
// matrix_processor_testbench.svmodule matrix_processor_testbench; // Testbench module matrix_processor MATRIX_DUT(); // Instantiate matrix processor design under testinitialbegin// Dump waves$dumpfile("matrix_processor_testbench.vcd"); // Specify the VCD file$dumpvars(0, matrix_processor_testbench); // Dump all variables in the test module#1; // Wait for a time unit$display("Testbench: Starting matrix processor validation...");$display(); // Display empty line// Wait for design to complete#10;$display("Testbench: Matrix processor validation completed!");endendmodule
Verilator Simulation Output:
================================================================================
Matrix Processor: Starting operations...
Matrix values and row sums:
Row 0 sum = 6
Row 1 sum = 10
Row 2 sum = 14
Row 3 sum = 18
Matrix Processor: Operations completed.
Testbench: Starting matrix processor validation...
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_11__matrix_processor/obj_dir directory...
Chapter_4_examples/example_11__matrix_processor/obj_dir removed successfully.
0
repeat Statements
The repeat statement executes a block a specified number of times.
SystemVerilog supports break and continue statements for loop control.
break Statement
The break statement exits the innermost loop immediately.
for (int i = 0; i < 100; i++) beginif (error_condition)break;// normal processingend
continue Statement
The continue statement skips the rest of the current iteration and continues with the next iteration.
for (int i = 0; i < 100; i++) beginif (skip_condition)continue;// processing for valid iterationsend
Example 14: Data Validation Loop
// data_validator.svmodule data_validator (); // Data validation processor design under testlogic [7:0] data_stream[100];logic [7:0] valid_data[$];initialbegin$display("Data Validator: Starting data validation process...");// Initialize test data with fixed seed approachfor (int i = 0; i < 100; i++) begin data_stream[i] = 8'((i * 17 + 42) % 256); // Generate pseudo-random patternend$display();$display("Data Validator: Test data initialized, beginning validation...");// Process data with validationforeach (data_stream[i]) begin// Skip invalid data (value 0 or 255)if (data_stream[i] == 0 || data_stream[i] == 255) begin$display("Data Validator: Skipping invalid data at index %0d: %0d", i, data_stream[i]);continue;end// Break on error pattern (redundant check since 255 is already filtered above)if (data_stream[i] == 8'hFF) begin$display("Data Validator: Error pattern detected at index %0d", i);break;end// Store valid data valid_data.push_back(data_stream[i]);$display("Data Validator: Valid data stored at index %0d: %0d", i, data_stream[i]);end$display("Data Validator: Processing completed!");$display("Data Validator: Processed %0d valid data items out of 100 total", valid_data.size());// Display first few valid items for verification$display("Data Validator: First 10 valid items:");for (int i = 0; i < 10 && i < valid_data.size(); i++) begin$display(" valid_data[%0d] = %0d", i, valid_data[i]);end$display();endendmodule
// data_validator_testbench.svmodule data_validator_testbench; // Testbench module data_validator DATA_VAL_DUT(); // Instantiate data validator design under testinitialbegin// Dump waves$dumpfile("data_validator_testbench.vcd"); // Specify the VCD file$dumpvars(0, data_validator_testbench); // Dump all variables in the test module#1; // Wait for a time unit$display(); // Display empty line$display("Testbench: Starting data validator verification...");$display(); // Display empty line// Wait for design to complete processing#100;$display("Testbench: Data validator verification completed!");$display("Testbench: Check output for validation results and statistics.");$display(); // Display empty lineendendmodule
Verilator Simulation Output:
================================================================================
Data Validator: Starting data validation process...
Data Validator: Test data initialized, beginning validation...
Data Validator: Valid data stored at index 0: 42
Data Validator: Valid data stored at index 1: 59
Data Validator: Valid data stored at index 2: 76
Data Validator: Valid data stored at index 3: 93
Data Validator: Valid data stored at index 4: 110
Data Validator: Valid data stored at index 5: 127
Data Validator: Valid data stored at index 6: 144
Data Validator: Valid data stored at index 7: 161
Data Validator: Valid data stored at index 8: 178
Data Validator: Valid data stored at index 9: 195
Data Validator: Valid data stored at index 10: 212
Data Validator: Valid data stored at index 11: 229
Data Validator: Valid data stored at index 12: 246
Data Validator: Valid data stored at index 13: 7
Data Validator: Valid data stored at index 14: 24
Data Validator: Valid data stored at index 15: 41
Data Validator: Valid data stored at index 16: 58
Data Validator: Valid data stored at index 17: 75
Data Validator: Valid data stored at index 18: 92
Data Validator: Valid data stored at index 19: 109
Data Validator: Valid data stored at index 20: 126
Data Validator: Valid data stored at index 21: 143
Data Validator: Valid data stored at index 22: 160
Data Validator: Valid data stored at index 23: 177
Data Validator: Valid data stored at index 24: 194
Data Validator: Valid data stored at index 25: 211
Data Validator: Valid data stored at index 26: 228
Data Validator: Valid data stored at index 27: 245
Data Validator: Valid data stored at index 28: 6
Data Validator: Valid data stored at index 29: 23
Data Validator: Valid data stored at index 30: 40
Data Validator: Valid data stored at index 31: 57
Data Validator: Valid data stored at index 32: 74
Data Validator: Valid data stored at index 33: 91
Data Validator: Valid data stored at index 34: 108
Data Validator: Valid data stored at index 35: 125
Data Validator: Valid data stored at index 36: 142
Data Validator: Valid data stored at index 37: 159
Data Validator: Valid data stored at index 38: 176
Data Validator: Valid data stored at index 39: 193
Data Validator: Valid data stored at index 40: 210
Data Validator: Valid data stored at index 41: 227
Data Validator: Valid data stored at index 42: 244
Data Validator: Valid data stored at index 43: 5
Data Validator: Valid data stored at index 44: 22
Data Validator: Valid data stored at index 45: 39
Data Validator: Valid data stored at index 46: 56
Data Validator: Valid data stored at index 47: 73
Data Validator: Valid data stored at index 48: 90
Data Validator: Valid data stored at index 49: 107
Data Validator: Valid data stored at index 50: 124
Data Validator: Valid data stored at index 51: 141
Data Validator: Valid data stored at index 52: 158
Data Validator: Valid data stored at index 53: 175
Data Validator: Valid data stored at index 54: 192
Data Validator: Valid data stored at index 55: 209
Data Validator: Valid data stored at index 56: 226
Data Validator: Valid data stored at index 57: 243
Data Validator: Valid data stored at index 58: 4
Data Validator: Valid data stored at index 59: 21
Data Validator: Valid data stored at index 60: 38
Data Validator: Valid data stored at index 61: 55
Data Validator: Valid data stored at index 62: 72
Data Validator: Valid data stored at index 63: 89
Data Validator: Valid data stored at index 64: 106
Data Validator: Valid data stored at index 65: 123
Data Validator: Valid data stored at index 66: 140
Data Validator: Valid data stored at index 67: 157
Data Validator: Valid data stored at index 68: 174
Data Validator: Valid data stored at index 69: 191
Data Validator: Valid data stored at index 70: 208
Data Validator: Valid data stored at index 71: 225
Data Validator: Valid data stored at index 72: 242
Data Validator: Valid data stored at index 73: 3
Data Validator: Valid data stored at index 74: 20
Data Validator: Valid data stored at index 75: 37
Data Validator: Valid data stored at index 76: 54
Data Validator: Valid data stored at index 77: 71
Data Validator: Valid data stored at index 78: 88
Data Validator: Valid data stored at index 79: 105
Data Validator: Valid data stored at index 80: 122
Data Validator: Valid data stored at index 81: 139
Data Validator: Valid data stored at index 82: 156
Data Validator: Valid data stored at index 83: 173
Data Validator: Valid data stored at index 84: 190
Data Validator: Valid data stored at index 85: 207
Data Validator: Valid data stored at index 86: 224
Data Validator: Valid data stored at index 87: 241
Data Validator: Valid data stored at index 88: 2
Data Validator: Valid data stored at index 89: 19
Data Validator: Valid data stored at index 90: 36
Data Validator: Valid data stored at index 91: 53
Data Validator: Valid data stored at index 92: 70
Data Validator: Valid data stored at index 93: 87
Data Validator: Valid data stored at index 94: 104
Data Validator: Valid data stored at index 95: 121
Data Validator: Valid data stored at index 96: 138
Data Validator: Valid data stored at index 97: 155
Data Validator: Valid data stored at index 98: 172
Data Validator: Valid data stored at index 99: 189
Data Validator: Processing completed!
Data Validator: Processed 100 valid data items out of 100 total
Data Validator: First 10 valid items:
valid_data[0] = 42
valid_data[1] = 59
valid_data[2] = 76
valid_data[3] = 93
valid_data[4] = 110
valid_data[5] = 127
valid_data[6] = 144
valid_data[7] = 161
valid_data[8] = 178
valid_data[9] = 195
Testbench: Starting data validator verification...
Testbench: Data validator verification completed!
Testbench: Check output for validation results and statistics.
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_14__data_validator/obj_dir directory...
Chapter_4_examples/example_14__data_validator/obj_dir removed successfully.
0
Example 15: Search Algorithm
functionint find_first_match(logic [7:0] array[], logic [7:0] target);foreach (array[i]) beginif (array[i] == target) beginreturn i; // Found match, return indexend// Skip processing for special valuesif (array[i] == 8'hXX) begincontinue;end// Additional processing could go hereendreturn -1; // Not foundendfunction
// find_first_match.svmodule array_searcher (); // Array search processor design under testlogic [7:0] test_array[50];logic [7:0] search_targets[5];int search_results[5];// Function to find first match in arrayfunctionint find_first_match(logic [7:0] array[], logic [7:0] target);foreach (array[i]) beginif (array[i] == target) beginreturn i; // Found match, return indexend// Skip processing for special values (undefined/don't care)if (array[i] === 8'bxxxxxxxx) begin$display("Array Searcher: Skipping undefined value at index %0d", i);continue;end// Additional processing could go here for logging// $display("Array Searcher: Checking index %0d, value %0d", i, array[i]);endreturn -1; // Not foundendfunctioninitialbegin$display("Array Searcher: Starting array search demonstration...");$display();// Initialize test array with sample datafor (int i = 0; i < 50; i++) beginif (i == 15 || i == 25) begin test_array[i] = 8'bxxxxxxxx; // Insert undefined valuesendelsebegin test_array[i] = 8'((i * 7 + 13) % 128); // Generate test patternendend// Define search targets search_targets[0] = 8'd20; search_targets[1] = 8'd50; search_targets[2] = 8'd99; search_targets[3] = 8'd0; search_targets[4] = 8'd127;$display("Array Searcher: Test array initialized with 50 elements");$display("Array Searcher: Undefined values inserted at indices 15 and 25");$display();// Display first 10 array elements for reference$display("Array Searcher: First 10 array elements:");for (int i = 0; i < 10; i++) beginif (test_array[i] === 8'bxxxxxxxx) begin$display(" test_array[%0d] = XX (undefined)", i);endelsebegin$display(" test_array[%0d] = %0d", i, test_array[i]);endend$display();// Perform searches$display("Array Searcher: Performing searches...");foreach (search_targets[j]) begin search_results[j] = find_first_match(test_array, search_targets[j]);if (search_results[j] >= 0) begin$display("Array Searcher: Target %0d found at index %0d", search_targets[j], search_results[j]);endelsebegin$display("Array Searcher: Target %0d not found in array", search_targets[j]);endend$display();$display("Array Searcher: Search operations completed!");// Summary of results$display("Array Searcher: Search Results Summary:");foreach (search_targets[k]) begin$display(" Target %0d: %s", search_targets[k], (search_results[k] >= 0) ? $sformatf("Found at index %0d", search_results[k]) : "Not found");end$display();endendmodule
// find_first_match_testbench.svmodule find_first_match_testbench; // Testbench module array_searcher SEARCH_DUT(); // Instantiate array searcher design under testinitialbegin// Dump waves$dumpfile("find_first_match_testbench.vcd"); // Specify the VCD file$dumpvars(0, find_first_match_testbench); // Dump all variables in the test module#1; // Wait for a time unit$display(); // Display empty line$display("Testbench: Starting array search function verification...");$display(); // Display empty line// Wait for design to complete processing#150;$display("Testbench: Array search function verification completed!");$display("Testbench: Check output for search results and function behavior.");$display(); // Display empty line// End simulation$finish;endendmodule
Verilator Simulation Output:
================================================================================
Array Searcher: Starting array search demonstration...
Array Searcher: Test array initialized with 50 elements
Array Searcher: Undefined values inserted at indices 15 and 25
Array Searcher: First 10 array elements:
test_array[0] = 13
test_array[1] = 20
test_array[2] = 27
test_array[3] = 34
test_array[4] = 41
test_array[5] = 48
test_array[6] = 55
test_array[7] = 62
test_array[8] = 69
test_array[9] = 76
Array Searcher: Performing searches...
Array Searcher: Target 20 found at index 1
Array Searcher: Target 50 not found in array
Array Searcher: Target 99 not found in array
Array Searcher: Target 0 found at index 15
Array Searcher: Target 127 not found in array
Array Searcher: Search operations completed!
Array Searcher: Search Results Summary:
Target 20: Found at index 1
Target 50: Not found
Target 99: Not found
Target 0: Found at index 15
Target 127: Not found
Testbench: Starting array search function verification...
Testbench: Array search function verification completed!
Testbench: Check output for search results and function behavior.
================================================================================
Process finished with return code: 0
Removing Chapter_4_examples/example_15__find_first_match/obj_dir directory...
Chapter_4_examples/example_15__find_first_match/obj_dir removed successfully.
0
Best Practices and Guidelines
Control Flow Best Practices
Use appropriate control structures:
if-else for simple conditions
case for multi-way branching
unique case for mutually exclusive conditions
priority case for prioritized conditions
Always include default cases:
case (opcode)4'b0000: result = a + b;4'b0001: result = a - b;default: result = 8'h00; // Always includeendcase
Use proper blocking assignments:
Use = in always_comb blocks
Use <= in always_ff blocks
Avoid complex nested conditions:
// Instead of deeply nested if-elseif (condition1) beginif (condition2) beginif (condition3) begin// deeply nestedendendend// Use early returns or case statementscase ({condition1, condition2, condition3})3'b111: // handle case3'b110: // handle casedefault: // handle defaultendcase
Synthesis Considerations
Combinational vs Sequential Logic:
Use always_comb for combinational logic
Use always_ff for sequential logic
Avoid latches:
Always assign values to all outputs in all branches
Use default assignments
Resource implications:
Complex case statements may require large multiplexers