Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Verilog HDL Practice Problems from HDLBits

Tech 1

Introduction to Verilog HDL

Basic Concepts

Fundamental Modules

// Constant output module
module constant_output (
    output logic one
);
    assign one = 1'b1;
endmodule

// Zero output module
module zero_output (
    output logic zero
);
    assign zero = 1'b0;
endmodule

Wire Connections

// Signal passthrough
module signal_passthrough (
    input in,
    output out
);
    assign out = in;
endmodule

// Multiple wire connections
module wire_connections (
    input a, b, c,
    output w, x, y, z
);
    assign w = a;
    assign x = b;
    assign y = b;
    assign z = c;
endmodule

Basic Gates

// NOT gate implementation
module not_gate (
    input in,
    output out
);
    assign out = ~in;
endmodule

// AND gate implementation
module and_gate (
    input a,
    input b,
    output out
);
    assign out = a & b;
endmodule

// NOR gate implementation
module nor_gate (
    input a,
    input b,
    output out
);
    assign out = ~(a | b);
endmodule

// XNOR gate implementation
module xnor_gate (
    input a,
    input b,
    output out
);
    assign out = a ~^ b;
endmodule

Vector Operations

Vector Basics

// Vector handling
module vector_basic (
    input [2:0] vec,
    output [2:0] outv,
    output o2,
    output o1,
    output o0
);
    assign outv = vec;
    assign o2 = vec[2];
    assign o1 = vec[1];
    assign o0 = vec[0];
endmodule

Vector Manipulation

// Byte selection
module byte_selector (
    input [15:0] in,
    output [7:0] upper_byte,
    output [7:0] lower_byte
);
    assign upper_byte = in[15:8];
    assign lower_byte = in[7:0];
endmodule

// Vector reversal
module vector_reverse (
    input [31:0] in,
    output [31:0] out
);
    assign out = {in[7:0], in[15:8], in[23:16], in[31:24]};
endmodule

Module Hierarchy

Module Instantiation

// Named port connection
module named_port (
    input a,
    input b,
    output out
);
    submodule u_sub (
        .in1(a),
        .in2(b),
        .out(out)
    );
endmodule

Sequential Module Chain

// Three-stage pipeline
module three_stage (
    input clk,
    input d,
    output q
);
    wire stage1, stage2;
    dff_stage u1 (clk, d, stage1);
    dff_stage u2 (clk, stage1, stage2);
    dff_stage u3 (clk, stage2, q);
endmodule

Procedural Blocks

Combinational Logic

// Always block for combinational logic
module combo_logic (
    input a,
    input b,
    output logic result
);
    always_comb begin
        result = a & b;
    end
endmodule

Sequential Logic

// Clocked always block
module clocked_logic (
    input clk,
    input a,
    input b,
    output logic q
);
    always_ff @(posedge clk) begin
        q <= a ^ b;
    end
endmodule

Conditional Logic

// If statement implementation
module conditional_logic (
    input a,
    input b,
    input select1,
    input select2,
    output logic out
);
    always_comb begin
        if (select1 && select2)
            out = b;
        else
            out = a;
    end
endmodule

Case Statement

// Multiplexer using case
module case_mux (
    input [2:0] sel,
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output logic [3:0] out
);
    always_comb begin
        case (sel)
            3'd0: out = data0;
            3'd1: out = data1;
            3'd2: out = data2;
            3'd3: out = data3;
            3'd4: out = data4;
            3'd5: out = data5;
            default: out = 4'b0000;
        endcase
    end
endmodule

Advanced Verilog Features

Ternary Operator

// Minimum finder
module minimum_finder (
    input [7:0] a, b, c, d,
    output [7:0] min_val
);
    wire [7:0] min_ab, min_cd;
    assign min_ab = (a < b) ? a : b;
    assign min_cd = (c < d) ? c : d;
    assign min_val = (min_ab < min_cd) ? min_ab : min_cd;
endmodule

Reduction Operators

// Parity calculator
module parity_calc (
    input [7:0] in,
    output parity
);
    assign parity = ^in;
endmodule

Generate Blocks

// 100-bit adder using generate
module wide_adder (
    input [99:0] a, b,
    input carry_in,
    output [99:0] sum,
    output carry_out
);
    wire [99:0] carries;
    full_adder fa0 (.a(a[0]), .b(b[0]), .cin(carry_in), .sum(sum[0]), .cout(carries[0]));
    
    genvar i;
    generate
        for (i = 1; i < 100; i++) begin : adder_loop
            full_adder fi (.a(a[i]), .b(b[i]), .cin(carries[i-1]), .sum(sum[i]), .cout(carries[i]));
        end
    endgenerate
    
    assign carry_out = carries[99];
endmodule

// Full adder sub-module
module full_adder (
    input a, b, cin,
    output sum, cout
);
    assign {cout, sum} = a + b + cin;
endmodule

Combinational Circuits

Multiplexers

// 2-to-1 multiplexer
module mux2to1 (
    input a, b,
    input sel,
    output out
);
    assign out = sel ? b : a;
endmodule

// 256-to-1 multiplexer
module mux256to1 (
    input [255:0] in,
    input [7:0] sel,
    output out
);
    assign out = in[sel];
endmodule

// 4-bit wide 256-to-1 mux
module wide_mux256to1 (
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out
);
    assign out = in[sel*4 +: 4];
endmodule

Arithmetic Circuits

// Half adder
module half_adder (
    input a, b,
    output sum,
    output carry
);
    assign sum = a ^ b;
    assign carry = a & b;
endmodule

// Full adder
module full_adder (
    input a, b, cin,
    output sum,
    output cout
);
    assign {cout, sum} = a + b + cin;
endmodule

// Signed overflow detection
module signed_adder (
    input [7:0] a, b,
    output [7:0] sum,
    output overflow
);
    assign sum = a + b;
    assign overflow = (a[7] & b[7] & ~sum[7]) | (~a[7] & ~b[7] & sum[7]);
endmodule

Karnaugh Map Implementation

// 3-variable function
module kmap_3var (
    input a, b, c,
    output out
);
    assign out = a | b | c;
endmodule

// 4-variable function
module kmap_4var (
    input a, b, c, d,
    output out
);
    assign out = (~b & ~c) | (~a & ~d) | (a & c & d) | (b & c & d);
endmodule

Sequential Circuits

Latches and Flip-Flops

// D flip-flop with sync reset
module dff_sync_reset (
    input clk,
    input reset,
    input [7:0] d,
    output logic [7:0] q
);
    always_ff @(posedge clk) begin
        if (reset)
            q <= 8'b0;
        else
            q <= d;
    end
endmodule

// D flip-flop with async reset
module dff_async_reset (
    input clk,
    input areset,
    input [7:0] d,
    output logic [7:0] q
);
    always_ff @(posedge clk or posedge areset) begin
        if (areset)
            q <= 8'b0;
        else
            q <= d;
    end
endmodule

// D latch
module d_latch (
    input d,
    input enable,
    output logic q
);
    always_latch begin
        if (enable)
            q <= d;
    end
endmodule

Counters

// 4-bit binary counter
module binary_counter (
    input clk,
    input reset,
    output logic [3:0] count
);
    always_ff @(posedge clk) begin
        if (reset)
            count <= 4'b0;
        else
            count <= count + 1;
    end
endmodule

// Decade counter (0-9)
module decade_counter (
    input clk,
    input reset,
    output logic [3:0] count
);
    always_ff @(posedge clk) begin
        if (reset)
            count <= 4'b0;
        else if (count < 9)
            count <= count + 1;
        else
            count <= 4'b0;
    end
endmodule

Shift Registers

// 4-bit shift register
module shift_reg_4bit (
    input clk,
    input areset,
    input load,
    input enable,
    input [3:0] data,
    output logic [3:0] q
);
    always_ff @(posedge clk or posedge areset) begin
        if (areset)
            q <= 4'b0;
        else if (load)
            q <= data;
        else if (enable)
            q <= {1'b0, q[3:1]};
    end
endmodule

// LFSR implementation
module lfsr_5bit (
    input clk,
    input reset,
    output logic [4:0] q
);
    always_ff @(posedge clk) begin
        if (reset)
            q <= 5'h1;
        else begin
            q <= {q[3:0], q[4] ^ q[2]};
        end
    end
endmodule

Finite State Machines

Simple FSMs

// Two-state FSM
module two_state_fsm (
    input clk,
    input reset,
    input in,
    output out
);
    typedef enum logic [1:0] {
        STATE_A = 2'b00,
        STATE_B = 2'b01
    } state_t;
    
    state_t current_state, next_state;
    
    always_ff @(posedge clk) begin
        if (reset)
            current_state <= STATE_B;
        else
            current_state <= next_state;
    end
    
    always_comb begin
        case (current_state)
            STATE_A: next_state = in ? STATE_A : STATE_B;
            STATE_B: next_state = in ? STATE_B : STATE_A;
        endcase
    end
    
    assign out = (current_state == STATE_B);
endmodule

Complex FSMs

// Lemmings behavior FSM
module lemmings_fsm (
    input clk,
    input areset,
    input bump_left,
    input bump_right,
    input ground,
    output logic walk_left,
    output logic walk_right,
    output logic falling
);
    typedef enum logic [1:0] {
        LEFT = 2'b00,
        RIGHT = 2'b01,
        FALL_L = 2'b10,
        FALL_R = 2'b11
    } state_t;
    
    state_t state, next_state;
    
    always_ff @(posedge clk or posedge areset) begin
        if (areset)
            state <= LEFT;
        else
            state <= next_state;
    end
    
    always_comb begin
        case (state)
            LEFT: next_state = ground ? (bump_left ? RIGHT : LEFT) : FALL_L;
            RIGHT: next_state = ground ? (bump_right ? LEFT : RIGHT) : FALL_R;
            FALL_L: next_state = ground ? LEFT : FALL_L;
            FALL_R: next_state = ground ? RIGHT : FALL_R;
        endcase
    end
    
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign falling = (state == FALL_L) || (state == FALL_R);
endmodule

Verification and Testbenches

Clock Generation

`timescale 1ns/1ps

module clock_generator;
    reg clk;
    initial begin
        clk = 0;
        forever #5 clk = ~clk;
    end
    
    dut test_dut (.clk(clk));
endmodule

Basic Testbench

`timescale 1ns/1ps

module basic_tb;
    reg a, b;
    wire out;
    
    initial begin
        a = 0; b = 0;
        #10 a = 1;
        #10 b = 1;
        #10 a = 0;
        #20 b = 0;
    end
    
    and_gate u_and (.a(a), .b(b), .out(out));
endmodule

Sequential Circuit Test

`timescale 1ns/1ps

module sequential_tb;
    reg clk, reset, t;
    wire q;
    
    initial begin
        clk = 0;
        reset = 1;
        t = 0;
        #10 reset = 0;
        #5 t = 1;
    end
    
    always #5 clk = ~clk;
    
    t_flip_flop u_tff (.clk(clk), .reset(reset), .t(t), .q(q));
endmodule

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.