Manage your HDL problems and test cases
| Title | Description | Difficulty | Module Name | Slug | Created At | Actions |
|---|---|---|---|---|---|---|
| Half Adder | # Half Adder in Verilog
## Introduction
A **Half Adder** is the simplest digital circuit that performs binary addition.
It takes two **1-bit inputs** and produces two outputs:
- **Sum** → result of XOR operation
- **Carry** → result of AND operation
In this tutorial, we will describe how to design and test a Half Adder using **RTL (Register Transfer Level) modeling** in Verilog.
---
## Step 1: Understand the Logic
The Half Adder works with the following logic equations:
- **Sum Equation**:
Sum = A ⊕ B
- **Carry Equation**:
Carry = A · B
### Truth Table
| a | b | sum | carry |
|---|---|-----|-------|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
---
## Step 2: RTL Modeling Concept
In RTL style:
- Outputs are declared as **reg** because they are assigned inside an `always` block.
- The block `always @(*)` is used for **combinational logic**.
- Inside the block, we describe the equations for **sum** and **carry**.
---
## Step 3: Writing the Testbench
A **testbench** is used to apply all input combinations and observe the outputs.
It should include:
1. Declaration of input regs and output wires.
2. Instantiation of the Half Adder module.
3. An `initial` block where inputs are changed over time.
4. Simulation ending with `$finish`.
---
## Step 4: Simulation and Verification
1. Compile the design and testbench with your simulator (e.g., `iverilog`).
2. Run the simulation executable.
3. Open the waveform file (e.g., in **GTKWave**) to observe the signals.
4. Compare results with the truth table to confirm correctness.
---
## Common Mistakes to Avoid
- Forgetting to declare `sum` and `carry` as **reg** when using RTL modeling.
- Not using `always @(*)`, which may cause incomplete sensitivity list issues.
- Confusing the XOR (`^`) with OR (`|`) operator when writing equations.
---
| Easy | half_adder | half-adder | Sep 7, 2025 | |
| 1 to 2 Decoder | # Implement Decoder in Verilog (gate level)
## Objective
A **Decoder** is a combinational circuit that converts **n input lines** into **2ⁿ unique outputs**.
It activates exactly one output line corresponding to the binary code of the input.
In this tutorial, we will design a **2-to-4 decoder** in Verilog and verify it using a testbench.
---
## Explanation (How it works)
A **2-to-4 decoder** has:
- **Inputs**: `A1, A0` (2-bit binary input)
- **Outputs**: `D0, D1, D2, D3`
Decoding rules:
- If input = `00` → `D0 = 1`
- If input = `01` → `D1 = 1`
- If input = `10` → `D2 = 1`
- If input = `11` → `D3 = 1`
All other outputs remain `0`.
**Boolean equations:**
- `D0 = ~A1 & ~A0`
- `D1 = ~A1 & A0`
- `D2 = A1 & ~A0`
- `D3 = A1 & A0`
---
## Requirements
1. Create a Verilog module named `decoder2to4` with:
- Inputs: `A1, A0`
- Outputs: `D0, D1, D2, D3`
2. Implement the Boolean equations for each output.
3. Write a **`testbench`** module:
- Apply all 4 input combinations (`00`, `01`, `10`, `11`).
- Verify that exactly one output is active at a time.
---
## Expected Truth Table
| A1 | A0 | D0 | D1 | D2 | D3 |
|----|----|----|----|----|----|
| 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 | 0 | 1 |
---
## Test Plan (What to do)
1. Simulate `testbench` and apply all input combinations.
2. Confirm only **one output is high** for each input code.
3. Compare simulation results with the truth table.
---
## Common Pitfalls
- Forgetting to invert the inputs for equations of `D0` and `D1`.
- Activating multiple outputs at once (incorrect).
- Mixing up decoder vs encoder (decoder expands inputs, encoder compresses inputs).
---
## Extension (Challenge)
- Design a **3-to-8 decoder** using the same method.
- Add an **enable input (EN)** that controls whether outputs are active or forced to `0`.
- Implement a **hierarchical decoder** (e.g., build a 3-to-8 decoder using two 2-to-4 decoders).
| Easy | one_to_2_decoder | 1-to-2-decoder | Sep 7, 2025 | |
| 4 to 2 Encoder | # Problem: Implement Encoder in Verilog (Gate Level)
## Objective
An **Encoder** is a combinational circuit that converts **2ⁿ input lines** into **n output lines**.
At any time, only one input should be active (logic 1).
The encoder outputs the binary code corresponding to the active input line.
In this tutorial, we will design a **4-to-2 encoder** in Verilog and verify it using a testbench.
---
## Explanation (How it works)
A **4-to-2 encoder** has:
- **Inputs**: `I0, I1, I2, I3`
- **Outputs**: `Y1, Y0`
Encoding rules:
- If `I0 = 1` → Output = `00`
- If `I1 = 1` → Output = `01`
- If `I2 = 1` → Output = `10`
- If `I3 = 1` → Output = `11`
**Boolean equations:**
- `Y0 = I1 | I3`
- `Y1 = I2 | I3`
Limitation: If more than one input is `1`, the output becomes undefined.
(That’s why we use a **Priority Encoder** in real designs.)
---
## Requirements
1. Create a Verilog module named `encoder4to2` with:
- Inputs: `I0, I1, I2, I3`
- Outputs: `Y0, Y1`
2. Implement the Boolean equations:
- `assign Y0 = I1 | I3;`
- `assign Y1 = I2 | I3;`
3. Write a `testbench` module:
- Activate one input at a time.
- Verify that outputs match the expected binary code.
---
## Expected Truth Table
| I3 | I2 | I1 | I0 | Y1 | Y0 |
|----|----|----|----|----|----|
| 0 | 0 | 0 | 1 | 0 | 0 |
| 0 | 0 | 1 | 0 | 0 | 1 |
| 0 | 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 0 | 0 | 1 | 1 |
---
## Test Plan (What to do)
1. Apply test vectors where exactly one input is `1`.
2. Check that the outputs match the binary code of the active input.
3. (Optional) Try multiple active inputs and observe undefined behavior.
---
## Common Pitfalls
- Forgetting that only **one input should be 1 at a time**.
- Confusing encoder with **decoder** (they are opposites).
- Mixing up the order of outputs (`Y1` is MSB, `Y0` is LSB).
---
## Extension (Challenge)
- Implement an **8-to-3 encoder** using our text editor.
- Upgrade the design to a **Priority Encoder** (gives highest priority to the highest-numbered input when multiple inputs are active).
| Easy | encoder4_to_2 | 4-to-2-encoder | Sep 7, 2025 | |
| Half Subtractor | # Implement Half Subtractor in Verilog (gate level)
## Objective
A **Half Subtractor** is a combinational circuit that subtracts one 1-bit binary input (**b**) from another (**a**).
It produces two outputs:
- **Difference (D)** → result of subtraction
- **Borrow (B)** → indicates when a borrow is required
In this tutorial, you will design a half subtractor using Verilog and test it with all input combinations.
---
## Explanation (How it works)
The half subtractor handles **subtraction of two bits only** — it cannot handle borrow from a previous stage (that’s why it’s *half*).
- **Difference Equation:**
`D = a ⊕ b`
- **Borrow Equation:**
`B = (~a) & b`
(Borrow is needed when `a = 0` and `b = 1`.)
---
## Requirements
1. Create a Verilog module named `half_subtractor` with:
- Inputs: `a`, `b`
- Outputs: `diff`, `borrow`
2. Implement using the logic equations:
- `assign diff = a ^ b;`
- `assign borrow = (~a) & b;`
3. Write a **`testbench`** module to verify:
- Apply all 4 input combinations (`00`, `01`, `10`, `11`).
- Observe difference and borrow.
---
## Expected Truth Table
| a | b | diff | borrow |
|---|---|------|--------|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 |
---
## Test Plan (What to do)
1. Simulate `testbench` and inspect signals `a, b, diff, borrow` in waveforms.
2. Verify `diff = a ⊕ b` and `borrow = (~a) & b` for all inputs.
3. Ensure truth table matches simulation results.
---
## Common Pitfalls
- Forgetting to invert `a` in the borrow equation.
- Using `a - b` directly in Verilog (not recommended for logic design tutorials).
- Not testing all input cases.
---
## Extension (Challenge)
- Compare the circuit with a **Full Adder** and notice the symmetry between addition and subtraction.
| Easy | half_subtractor | half-subtractor | Sep 7, 2025 | |
| Full Adder (gate level) | # Problem: Implement Full Adder in Verilog Using gate level modeling
## Objective
A **Full Adder** adds three 1-bit inputs — two operands (**a**, **b**) and a carry-in (**cin**) — and produces:
- **sum** (1 bit)
- **cout** (carry-out, 1 bit)
You’ll design the full adder and verify it with all input combinations.
---
## Explanation (How it works)
Think of column-wise binary addition:
- The **sum** bit is the XOR of all three inputs.
- The **carry-out** goes high when at least two of the inputs are 1.
Two common realizations:
1) **Equation form**
- `sum = a ^ b ^ cin`
- `cout = (a & b) | (cin & (a ^ b))`
2) **Two half-adders + OR**
- Half-Adder1: `s1 = a ^ b`, `c1 = a & b`
- Half-Adder2: `sum = s1 ^ cin`, `c2 = s1 & cin`
- `cout = c1 | c2`
---
## Requirements
1. Create a Verilog module named `full_adder` with:
- Inputs: `a`, `b`, `cin`
- Outputs: `sum`, `cout`
2. Implement using either the **equation form** or **two half-adders** method.
3. Write a **`testbench`** module to verify the design:
- Apply all 8 input combinations for `{a,b,cin}` from `000` to `111`.
- Check `sum` and `cout` against the truth table (use waveforms; no `$display` needed).
---
## Expected Truth Table
| a | b | cin | sum | cout |
|---|---|-----|-----|------|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
---
## Test Plan (What to do)
1. Simulate the `testbench` and inspect waveforms for `a, b, cin, sum, cout`.
2. Verify that `sum` toggles as XOR of all three, and `cout` goes high when ≥2 inputs are 1.
3. (Optional) Add small delays between vector changes so edges are visible in the VCD.
---
## Common Pitfalls
- Mixing up `cout` equation: ensure `cout = (a & b) | (cin & (a ^ b))`.
- Not testing all 8 combinations.
- Forgetting to name the testbench module exactly **`testbench`**.
---
## Extension (Challenge)
- Chain four `full_adder` modules to build a **4-bit ripple-carry adder** with `cin` and `cout`.
- Use our editor and try it out there
| Easy | full_adder | full-adder-gate-level | Sep 7, 2025 | |
| Half Adder(Gate level) | # Problem: Implement Half Adder in Verilog
## Objective
A **Half Adder** is a basic combinational circuit that performs the addition of two 1-bit binary numbers.
It produces two outputs:
- **Sum (S)** → XOR of inputs
- **Carry (C)** → AND of inputs
In this tutorial, you will design a half adder using Verilog and test it with all input combinations.
---
## Explanation
The half adder cannot handle carry-in from previous additions (that’s why it’s called *half*).
It is the simplest building block for binary addition.
- **Sum Equation:** `S = A ⊕ B`
- **Carry Equation:** `C = A · B`
---
## Requirements
1. Create a Verilog module named `half_adder` with:
- Two inputs: `a`, `b`
- Two outputs: `sum`, `carry`
2. Implement the equations:
- `assign sum = a ^ b;`
- `assign carry = a & b;`
3. Write a `testbench` module to verify the half adder:
- Apply all 4 input combinations of `a` and `b` (00, 01, 10, 11).
- Check `sum` and `carry`.
---
## Expected Truth Table
| a | b | sum | carry |
|---|---|-----|-------|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| Easy | half_adder | half-adder-gate-level | Sep 7, 2025 | |
| XOR | # Implement XOR Gate in Verilog
## Objective
Design and verify a simple 2-input XOR gate using Verilog.
The design should be tested using a testbench that applies all possible input combinations.
---
## Requirements
1. Create a Verilog module named `xor_gate` with:
- Two inputs: `a`, `b`
- One output: `y`
- Function: `y = a ^ b`
2. Write a `testbench` module to verify the XOR gate:
- Apply all 4 input combinations of `a` and `b` (00, 01, 10, 11).
- Observe the output `y` for correctness.
---
| Easy | xor_gate | xor | Sep 7, 2025 | |
| AND gate | # Implement AND Gate in Verilog
## Objective
Design and verify a simple 2-input AND gate using Verilog.
The design should be tested using a testbench that applies all possible input combinations.
---
## Requirements
1. Create a Verilog module named `and_gate` with:
- Two inputs: `a`, `b`
- One output: `y`
- Function: `y = a & b`
2. Write a `testbench` module to verify the AND gate:
- Apply all 4 input combinations of `a` and `b` (00, 01, 10, 11).
- Observe the output `y` for correctness.
---
| Easy | and_gate | and-gate | Sep 7, 2025 | |
| 4-bit Shift Register | # 4-bit Shift Register
## Problem Description
Implement a 4-bit shift register that shifts data to the left on each clock cycle.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- `in`: 1-bit serial input
- Output:
- `out`: 4-bit parallel output
## Expected Behavior
- On reset: Clear all bits to 0
- On each clock edge: Shift left, new bit enters from right (LSB)
- out[3] = previous out[2], out[2] = previous out[1], out[1] = previous out[0], out[0] = in | Easy | shift_reg | shift-reg | Aug 25, 2025 | |
| 4-bit Up Counter | # 4-bit Up Counter
## Problem Description
Implement a 4-bit up counter that increments on each clock cycle.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- Output:
- `count`: 4-bit counter output
## Expected Behavior
- On reset: count = 0
- On each clock edge: count = count + 1
- Counter wraps around from 15 to 0 | Easy | up_counter | up-counter | Aug 25, 2025 | |
| Scalar Array Logic | # Scalar Array Logic
## Problem Description
Implement a module that uses a scalar array (1-bit elements) to store and retrieve values based on a selector.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- `sel`: 2-bit selector
- Output:
- `out`: 1-bit output
## Expected Behavior
- On reset: Initialize array with pattern [0, 1, 0, 1]
- On each clock edge: Output the value at array[sel] | Easy | scalar_array_logic | scalar-array-logic | Aug 25, 2025 | |
| 4-to-1 Multiplexer | # 4-to-1 Multiplexer
## Problem Description
Implement a 4-to-1 multiplexer that selects one of four input bits based on a 2-bit select signal.
## Module Interface
- Inputs:
- `sel`: 2-bit select signal
- `data`: 4-bit input data
- Output:
- `out`: 1-bit selected output
## Expected Behavior
- sel = 00: output data[0]
- sel = 01: output data[1]
- sel = 10: output data[2]
- sel = 11: output data[3] | Easy | mux4 | mux | Aug 25, 2025 | |
| Vector Array Logic | # Vector Array Logic
Implement a module that uses a vector array (4-bit elements) to store and retrieve values.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- `addr`: 2-bit address
- Output:
- `data_out`: 4-bit data output
## Expected Behavior
- On reset: Initialize array with values [0001, 0010, 0100, 1000]
- On each clock edge: Output the value at array[addr] | Hard | vector_array_logic | vector-array-logic | Aug 25, 2025 | |
| LED Blinker | # LED Blinker
## Problem Description
Create a simple LED blinker that toggles an LED output based on a clock signal.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- Output:
- `led`: LED output signal
## Expected Behavior
- On reset: LED should be off (0)
- On each clock edge: LED should toggle state | Easy | led_blinker | led-blinker | Aug 25, 2025 | |
| 2D Matrix Array | # 2D Matrix Array
## Problem Description
Implement a 4x4 matrix memory module that supports both read and write operations. The matrix should store 8-bit values and allow access via row and column selectors.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- `row_sel`: 2-bit row selector
- `col_sel`: 2-bit column selector
- `wr_en`: Write enable signal
- `din`: 8-bit data input
- Output:
- `dout`: 8-bit data output
## Expected Behavior
- On reset: All matrix elements initialized to 0
- When wr_en = 1: Write din to matrix[row_sel][col_sel]
- When wr_en = 0: Read matrix[row_sel][col_sel] to dout | Medium | matrix_2d_array | matrix-2d-array | Aug 25, 2025 | |
| FSM Toggle | # FSM Toggle
## Problem Description
Implement a simple finite state machine that toggles between two states on each clock cycle.
## Module Interface
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- Output:
- `state`: Current state (1-bit)
## Expected Behavior
- On reset: state = 0
- On each clock edge: state toggles between 0 and 1 | Easy | fsm_toggle | fsm-toggle | Aug 25, 2025 | |
| Parameterized Delay Line | # Parameterized Delay Line
## Problem Description
Implement a parameterized delay line that delays input data by one clock cycle. The module should be parameterized to support different data widths.
## Module Interface
- Parameter:
- `WIDTH`: Data width (default: 8)
- Inputs:
- `clk`: Clock signal
- `reset`: Reset signal (active high)
- `din`: WIDTH-bit data input
- Output:
- `dout`: WIDTH-bit delayed data output
## Expected Behavior
- On reset: Both delay register and output are set to 0
- On each clock edge: din is stored in delay register, previous delay value goes to dout | Easy | param_delay_line | param-delay-line | Aug 25, 2025 | |
| 4-bit Priority Encoder | # 4-bit Priority Encoder
## Problem Description
Implement a 4-bit priority encoder that converts the highest priority active input bit to a binary code.
## Module Interface
- Inputs:
- `in`: 4-bit input data
- Outputs:
- `out`: 2-bit encoded output
- `valid`: 1-bit valid signal
## Expected Behavior
- Priority (highest to lowest): in[3] > in[2] > in[1] > in[0]
- When in[3] = 1: out = 11, valid = 1
- When in[3] = 0 and in[2] = 1: out = 10, valid = 1
- When in[3:2] = 00 and in[1] = 1: out = 01, valid = 1
- When in[3:1] = 000 and in[0] = 1: out = 00, valid = 1
- When in = 0000: out = 00, valid = 0 | Medium | priority_encoder4 | priority-encoder4 | Aug 25, 2025 | |
| Register Wire Demo | # Register Wire Demo
## Problem Description
Implement a simple module demonstrating the difference between registers and wires in Verilog.
## Module Interface
- Inputs:
- `a`: 1-bit input
- `b`: 1-bit input
- Outputs:
- `wire_out`: Combinational output (wire)
- `reg_out`: Sequential output (register)
## Expected Behavior
- wire_out should be the combinational AND of a and b
- reg_out should be the registered AND of a and b (updated on clock edge) | Easy | reg_wire_demo | reg-wire-demo | Aug 25, 2025 | |
| 4-bit Ripple Carry Adder | # 4-bit Ripple Carry Adder
## Problem Description
Implement a 4-bit ripple carry adder that adds two 4-bit numbers along with a carry-in bit.
## Module Interface
- Inputs:
- `A`: 4-bit operand A
- `B`: 4-bit operand B
- `cin`: 1-bit carry input
- Outputs:
- `sum`: 4-bit sum output
- `cout`: 1-bit carry output
## Expected Behavior
- Performs binary addition: sum = A + B + cin
- cout is the carry out from the most significant bit | Easy | ripple_adder | ripple-carry | Aug 25, 2025 |