DV Interview Questions
DV Interview Questions
TOP PRODUCT
COMPANIES
APPLE, QUALCOMM,
INTEL, AMD, ARM, . .
Prasanthi Chanda
CASE-BASED INTERVIEW QUESTION 1
SOLUTION STRATEGY:
1. Use Gray code pointers to prevent glitches during pointer
transfer.
2. Use a dual-port memory array for simultaneous read and write.
3. Synchronize the write pointer to the read domain and the read
pointer to the write domain using 2-stage flip-flops.
4. Compare pointers safely in respective domains to generate full
and empty flags.
module async_fifo #(
parameter ADDR_WIDTH = 4,
parameter DATA_WIDTH = 8
)(
input wire wr_clk,
input wire rd_clk,
input wire rst,
input wire wr_en,
input wire rd_en,
input wire [DATA_WIDTH-1:0] wr_data,
output reg [DATA_WIDTH-1:0] rd_data,
output wire full,
output wire empty
);
// Write logic
always @(posedge wr_clk or posedge rst) begin
if (rst) begin
wr_ptr_bin <= 0;
wr_ptr_gray <= 0;
end else if (wr_en && !full) begin
mem[wr_ptr_bin[ADDR_WIDTH-1:0]] <= wr_data;
wr_ptr_bin <= wr_ptr_bin + 1;
wr_ptr_gray <= (wr_ptr_bin + 1) ^ ((wr_ptr_bin + 1) >> 1);
end
end
// Read logic
always @(posedge rd_clk or posedge rst) begin
if (rst) begin
rd_ptr_bin <= 0;
rd_ptr_gray <= 0;
rd_data <= 0;
end else if (rd_en && !empty) begin
rd_data <= mem[rd_ptr_bin[ADDR_WIDTH-1:0]];
rd_ptr_bin <= rd_ptr_bin + 1;
rd_ptr_gray <= (rd_ptr_bin + 1) ^ ((rd_ptr_bin + 1) >> 1);
end
end
// Synchronize read pointer to write clock domain
always @(posedge wr_clk or posedge rst) begin
if (rst) begin
rd_ptr_gray_sync1 <= 0;
rd_ptr_gray_sync2 <= 0;
end else begin
rd_ptr_gray_sync1 <= rd_ptr_gray;
rd_ptr_gray_sync2 <= rd_ptr_gray_sync1;
end
end
endmodule
CASE-BASED INTERVIEW QUESTION 2
SOLUTION STRATEGY:
1. Use AND gate-based clock gating to selectively disable the
clock when the module isn't active.
2. Ensure that the clock enable signal is synchronized with the
clock domain to prevent glitches.
3. Design the gating logic to only disable the clock when the
module is idle to save power.
module clock_gating (
input wire clk, // Input clock
input wire enable, // Clock enable signal
output wire gated_clk // Gated clock output
);
reg gated_clk_int;
endmodule
CASE-BASED INTERVIEW QUESTION 3
You are designing a priority encoder in Verilog for a system that has
8 inputs and outputs the binary representation of the highest
priority active input. If no input is active, the encoder should output
a default value of 3'b111. How would you design this system?
Asked in: NVIDIA, Broadcom, Intel, Qualcomm
SOLUTION STRATEGY:
1. Use a priority encoder design that checks the highest active bit
and outputs the corresponding binary value.
2. Ensure that if no input is active, the output is set to a default
value (3'b111).
3. Use a case statement or if-else logic to implement the priority
encoder functionality.
module priority_encoder (
input wire [7:0] in, // 8-bit input
output reg [2:0] out // 3-bit output (binary representation)
);
always @(*) begin
casez (in)
8'b1???????: out = 3'b000; // Highest priority is bit 7
8'b01??????: out = 3'b001; // Highest priority is bit 6
8'b001?????: out = 3'b010; // Highest priority is bit 5
8'b0001????: out = 3'b011; // Highest priority is bit 4
8'b00001??? : out = 3'b100; // Highest priority is bit 3
8'b000001??: out = 3'b101; // Highest priority is bit 2
8'b0000001?: out = 3'b110; // Highest priority is bit 1
8'b00000001: out = 3'b111; // Highest priority is bit 0
default: out = 3'b111; // Default case when no bit is set
endcase
end
endmodule
CASE-BASED INTERVIEW QUESTION 4
SOLUTION STRATEGY:
1. Implement a round-robin scheduling mechanism to ensure fair
access to the shared resource.
2. Use a priority encoder to select which master gets access based
on the round-robin policy.
3. Ensure that the arbiter can handle multiple requests and
provide access in a fair manner without starvation.
module round_robin_arbiter (
input wire clk, // Clock signal
input wire rst, // Reset signal
input wire [3:0] request, // 4-bit master request input
output reg [3:0] grant // 4-bit master grant output
);
endmodule
module sync_reset (
input wire clk, // Clock signal
input wire nreset, // Active-low reset signal
output reg [3:0] q // 4-bit output
);
endmodule
module low_power_clock_gating (
input wire clk, // Clock input
input wire enable, // Conditional enable signal
output wire gated_clk // Gated clock output
);
reg gated_clk_int;
endmodule
CASE-BASED INTERVIEW QUESTION 7
SOLUTION STRATEGY:
1. Implement the LFSR shift register using the specified
polynomial for feedback.
2. Use the XOR gates to combine the tapped bits for feedback
generation.
3. Ensure that the register continuously shifts with the clock.
module lfsr (
input wire clk, // Clock input
input wire rst, // Active-low reset
output reg [15:0] lfsr_out // 16-bit LFSR output
);
endmodule
CASE-BASED INTERVIEW QUESTION 8
SOLUTION STRATEGY:
1. Use a counter-based debounce mechanism to ensure stable
switching.
2. After detecting a change in the switch state, the counter should
wait for a stable period before allowing a state change in the
output.
3. Prevent multiple transitions within a short time window.
module debouncer (
input wire clk, // Clock input
input wire rst, // Active-low reset
input wire switch_in, // Noisy switch input
output reg switch_out // Debounced output
);
endmodule
endmodule
SOLUTION STRATEGY:
1. Use a counter to count the clock cycles and compare it with the
duty cycle input.
2. The PWM signal should be high for the number of cycles
proportional to the duty cycle and low for the remaining cycles.
module pwm_generator (
input wire clk, // Clock input
input wire [3:0] duty_cycle, // 4-bit duty cycle input (0 to 15)
output reg pwm_out // PWM output signal
);
endmodule
Design a circular buffer in Verilog with read and write pointers that
operate in different clock domains. The buffer should be
implemented using dual-port RAM and should handle the
read/write operation safely using synchronization techniques.
Asked in: Qualcomm, Broadcom, Intel, AMD
SOLUTION STRATEGY:
1. Use dual-port RAM to handle both read and write operations.
2. Implement synchronization of the write pointer in the read
clock domain to prevent metastability.
3. Use Gray code or two-flop synchronization for pointer transfer.
module circular_buffer (
input wire wr_clk, // Write clock input
input wire rd_clk, // Read clock input
input wire rst, // Active-low reset
input wire [7:0] wr_data, // Write data input
input wire wr_en, // Write enable input
input wire rd_en, // Read enable input
output reg [7:0] rd_data // Read data output
);
// Write operation
always @(posedge wr_clk or negedge rst) begin
if (~rst)
wr_ptr <= 4'b0000; // Reset write pointer
else if (wr_en)
wr_ptr <= wr_ptr + 1; // Increment write pointer
end
// Read operation
always @(posedge rd_clk or negedge rst) begin
if (~rst)
rd_ptr <= 4'b0000; // Reset read pointer
else if (rd_en)
rd_ptr <= rd_ptr + 1; // Increment read pointer
end
endmodule
CASE-BASED INTERVIEW QUESTION 12
SOLUTION STRATEGY:
1. Use a priority checking mechanism to determine the highest-
priority active input.
2. Implement a binary encoding for the highest-priority input.
3. Ensure that if no inputs are active, the output remains invalid.
module priority_encoder (
input wire [7:0] in, // 8 input signals
output reg [2:0] out, // 3-bit binary code output
output reg valid // Valid signal to indicate if any input is active
);
always @(*) begin
case (in)
8'b10000000: out = 3'b111;
8'b01000000: out = 3'b110;
8'b00100000: out = 3'b101;
8'b00010000: out = 3'b100;
8'b00001000: out = 3'b011;
8'b00000100: out = 3'b010;
8'b00000010: out = 3'b001;
8'b00000001: out = 3'b000;
default: out = 3'bxxx; // No active input
endcase
valid = (in != 8'b00000000); // If any input is active, valid = 1
end
endmodule
CASE-BASED INTERVIEW QUESTION 13
SOLUTION STRATEGY:
1. Use a counter to divide the input clock by the desired factor.
2. The division factor should be configurable using a parameter.
3. Ensure that the counter wraps around when the specified
division value is reached.
module frequency_divider #(
parameter DIV_FACTOR = 4 // Division factor, default value 4
)(
input wire clk, // Input clock
input wire rst, // Active-low reset
output reg divided_clk // Divided clock output
);
endmodule
SOLUTION STRATEGY:
1. Detect the positive edge of the input signal.
2. Generate a 1-cycle pulse synchronized with the clock when the
edge is detected.
3. Ensure proper synchronization and reset behavior.
module pulse_generator (
input wire clk, // Input clock
input wire rst, // Active-low reset
input wire signal, // Input signal
output reg pulse // 1-clock cycle wide pulse
);
reg signal_d; // Delayed signal
endmodule
SOLUTION STRATEGY:
1. Create two sets of request signals, one for each process
(Process 1 and Process 2).
2. Create allocation signals to indicate resource ownership.
3. Detect deadlock by checking if both processes are waiting for
the resources held by each other.
module deadlock_detector (
input wire p1_req, // Process 1 request for resource
input wire p2_req, // Process 2 request for resource
input wire r1_alloc, // Resource 1 allocation signal
input wire r2_alloc, // Resource 2 allocation signal
output reg deadlock_detected // Deadlock detected signal
);
always @(*) begin
// Check for deadlock condition: both processes waiting on each
other
if (p1_req && p2_req && r1_alloc && r2_alloc)
deadlock_detected = 1'b1; // Deadlock detected
else
deadlock_detected = 1'b0; // No deadlock
end
endmodule
SOLUTION STRATEGY:
1. Implement a state machine with three states: Idle, Moving Up,
and Moving Down.
2. Use button presses and floor requests to trigger state
transitions.
3. Ensure proper reset behavior.
module elevator_fsm (
input wire clk, // Clock input
input wire rst, // Active-low reset
input wire up_button, // Up button press
input wire down_button, // Down button press
output reg [1:0] state // Elevator state output
);
// State encoding
parameter IDLE = 2'b00;
parameter UP = 2'b01;
parameter DOWN = 2'b10;
endmodule
CASE-BASED INTERVIEW QUESTION 17
SOLUTION STRATEGY:
1. Use delay elements to simulate the propagation delay of
signals.
2. Check the setup and hold times against the flip-flop's operating
conditions.
3. Generate violation flags based on the timing analysis.
module timing_checker (
input wire clk, // Clock input
input wire rst, // Active-low reset
input wire d, // Data input
input wire q, // Flip-flop output
input wire clk_edge, // Clock edge
output reg setup_violation, // Setup violation output
output reg hold_violation // Hold violation output
);
reg [1:0] d_delayed;
// Check setup and hold violations
always @(posedge clk or negedge rst) begin
if (~rst) begin
d_delayed <= 2'b00;
setup_violation <= 1'b0;
hold_violation <= 1'b0;
end else begin
// Simulate setup and hold violation detection logic
d_delayed <= {d_delayed[0], d}; // Delay the data signal
// Check for setup violation (if data is stable before clock edge)
if (clk_edge && (d != d_delayed[1]))
setup_violation <= 1'b1;
else
setup_violation <= 1'b0;
// Check for hold violation (if data is not stable after clock
edge)
if (~clk_edge && (d != d_delayed[0]))
hold_violation <= 1'b1;
else
hold_violation <= 1'b0;
end
end
endmodule
You need to design a digital clock that displays the time in hours
(00-23), minutes (00-59), and seconds (00-59). The clock is driven by
a 1 Hz clock signal. The design should handle overflow correctly
(i.e., 59 seconds should increment the minute counter, and 59
minutes should increment the hour counter). The clock should also
handle reset functionality.
Asked in: Intel, NVIDIA, Apple, Broadcom
SOLUTION STRATEGY:
1. Use a counter-based approach to count seconds, minutes, and
hours.
2. Implement overflow logic for seconds and minutes.
3. Use reset to initialize the clock to 00:00:00.
module digital_clock (
input wire clk, // 1 Hz clock input
input wire rst, // Active-low reset
output reg [5:0] hours, // Hours (00-23)
output reg [5:0] minutes,// Minutes (00-59)
output reg [5:0] seconds // Seconds (00-59)
);
// State registers
reg [5:0] sec_cnt; // Seconds counter (0-59)
reg [5:0] min_cnt; // Minutes counter (0-59)
reg [5:0] hour_cnt; // Hours counter (0-23)
// Assign outputs
always @(*) begin
hours = hour_cnt;
minutes = min_cnt;
seconds = sec_cnt;
end
endmodule
SOLUTION STRATEGY:
1. Implement handshaking using the valid and ack signals to
synchronize the sender and receiver.
2. Use a FIFO buffer for storing data.
3. Handle overflow when the sender’s data is not consumed
quickly enough by the receiver and underflow when the
receiver reads from an empty FIFO.
module fifo_handshaking (
input wire clk, // Clock input
input wire rst, // Active-low reset
input wire [7:0] data_in, // Data input to FIFO
input wire valid_in, // Valid signal from sender
output reg ack_in, // Acknowledge signal from receiver
output reg [7:0] data_out, // Data output from FIFO
output reg valid_out, // Valid signal for receiver
input wire ack_out // Acknowledge signal from receiver
);
// FIFO buffer
reg [7:0] fifo [15:0]; // 16-deep FIFO for 8-bit data
reg [3:0] write_ptr, read_ptr;
reg full, empty;
endmodule
module circular_shift_register (
input wire clk, // Clock input
input wire rst, // Active-low reset
input wire [7:0] data_in, // Data input to the shift register
output reg [7:0] data_out,// Data output from the shift register
input wire shift_left, // Shift left control
input wire shift_right // Shift right control
);
reg [7:0] shift_reg; // 8-bit shift register
endmodule
SOLUTION STRATEGY:
1. Create a pipelined architecture with N stages.
2. Use registers to store partial products at each stage.
3. Support valid/ready handshaking and reset.
module pipelined_multiplier #(
parameter N = 8
)(
input wire clk,
input wire rst,
input wire valid_in,
input wire [N-1:0] a,
input wire [N-1:0] b,
output reg valid_out,
output reg [2*N-1:0] product
);
// Pipeline registers
reg [2*N-1:0] pipe_reg [0:N-1];
reg [N-1:0] a_reg [0:N-1];
reg [N-1:0] b_reg;
reg valid_pipe [0:N-1];
integer i;
always @(posedge clk or negedge rst) begin
if (!rst) begin
for (i = 0; i < N; i = i + 1) begin
pipe_reg[i] <= 0;
a_reg[i] <= 0;
valid_pipe[i] <= 0;
end
b_reg <= 0;
product <= 0;
valid_out <= 0;
end else begin
if (valid_in) begin
a_reg[0] <= a;
b_reg <= b;
pipe_reg[0] <= a[0] ? b : 0;
valid_pipe[0] <= 1;
end
endmodule
SOLUTION STRATEGY:
1. Use FSM for transmitter and receiver.
2. Support configurable BAUD_TICK count for baud rate.
3. Add error detection for frame issues (missing stop/start bits).
module uart_tx (
input wire clk,
input wire rst,
input wire [7:0] tx_data,
input wire tx_start,
output reg tx_line,
output reg tx_busy
);
reg [3:0] state;
reg [3:0] bit_cnt;
reg [9:0] tx_shift;
SOLUTION STRATEGY:
1. Use associative tag arrays with 4 blocks per set
2. Track usage for LRU with shift register or counter
3. Output hit/miss and read data
module set_assoc_cache #(
parameter INDEX_BITS = 4,
parameter TAG_BITS = 8
)(
input clk,
input rst,
input [TAG_BITS + INDEX_BITS - 1:0] addr,
input [31:0] write_data,
input wr_en,
output reg [31:0] read_data,
output reg hit
);
integer i;
always @(posedge clk or posedge rst) begin
if (rst) begin
for (i = 0; i < SETS; i = i + 1) begin
valid_array[0][i] <= 0;
valid_array[1][i] <= 0;
valid_array[2][i] <= 0;
valid_array[3][i] <= 0;
lru[i] <= 0;
end
hit <= 0;
end else begin
hit <= 0;
for (i = 0; i < 4; i = i + 1) begin
if (valid_array[i][index] && tag_array[i][index] == tag) begin
read_data <= data_array[i][index];
hit <= 1;
lru[index] <= i; // update LRU
end
end
SOLUTION STRATEGY:
1. FSM with states: IDLE, ACTIVATE, READ_CMD, WAIT,
READ_BURST
2. Simulate burst-read alignment and latency
3. Use shift register to simulate CAS latency
module ddr_read_ctrl (
input clk,
input rst,
input read_req,
input [15:0] addr,
output reg [31:0] data_out,
output reg valid
);
parameter LATENCY = 3;
reg [2:0] state;
reg [2:0] latency_cnt;
reg [31:0] mem [0:65535];
reg [1:0] burst_cnt;
reg [15:0] read_addr;
localparam IDLE = 0,
ACTIVATE = 1,
WAIT_LAT = 2,
BURST_READ = 3;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= IDLE;
valid <= 0;
end else begin
case (state)
IDLE: begin
valid <= 0;
if (read_req) begin
read_addr <= addr;
state <= ACTIVATE;
end
end
ACTIVATE: begin
latency_cnt <= LATENCY;
state <= WAIT_LAT;
end
WAIT_LAT: begin
if (latency_cnt == 0) begin
burst_cnt <= 0;
state <= BURST_READ;
end else begin
latency_cnt <= latency_cnt - 1;
end
end
BURST_READ: begin
data_out <= mem[read_addr + burst_cnt];
valid <= 1;
burst_cnt <= burst_cnt + 1;
if (burst_cnt == 3)
state <= IDLE;
end
endcase
end
end
endmodule
CASE-BASED INTERVIEW QUESTION 25
SOLUTION STRATEGY:
1. Circular buffer with head/tail pointers
2. Maintain validity and tags for each entry
3. Commit in order from head
4. Support flush on exception
module reorder_buffer #(
parameter WIDTH = 8,
parameter TAG_WIDTH = 4
)(
input clk,
input rst,
input issue,
input commit,
input [TAG_WIDTH-1:0] tag_in,
input exception,
output reg [TAG_WIDTH-1:0] tag_out,
output reg valid_out
);
SOLUTION STRATEGY:
1. Use FSMs for transfer logic per channel
2. Priority encoder to choose which channel runs
3. Use AXI-lite or simple interface for memory
module dma_controller (
input clk,
input rst,
input [3:0] start, // Start signal per channel
input [31:0] src_addr[3:0],
input [31:0] dest_addr[3:0],
input [15:0] length[3:0],
output reg [3:0] done // Done signal per channel
);
if (|start) begin
busy <= 1;
count <= length[current_channel];
end
end else begin
// Simulate transfer
if (count > 0) begin
count <= count - 1;
end else begin
done[current_channel] <= 1;
busy <= 0;
end
end
end
end
endmodule
module pe (
input clk,
input rst,
input [7:0] a_in,
input [7:0] b_in,
input [15:0] c_in,
output reg [7:0] a_out,
output reg [7:0] b_out,
output reg [15:0] c_out
);
always @(posedge clk or posedge rst) begin
if (rst) begin
a_out <= 0;
b_out <= 0;
c_out <= 0;
end else begin
c_out <= c_in + a_in * b_in;
a_out <= a_in;
b_out <= b_in;
end
end
endmodule
CASE-BASED INTERVIEW QUESTION 28
module axi_lite_slave (
input clk,
input rst,
input [3:0] awaddr,
input awvalid,
output reg awready,
// Write Data
if (wvalid && !wready) begin
regs[awaddr[3:2]] <= wdata;
wready <= 1;
bvalid <= 1;
end else wready <= 0;
// Read
if (arvalid && !arready) begin
rdata <= regs[araddr[3:2]];
arready <= 1;
rvalid <= 1;
end else begin
arready <= 0;
if (rvalid && rready) rvalid <= 0;
end
end
end
endmodule
CASE-BASED INTERVIEW QUESTION 29
module ex_stage (
input [31:0] reg_rs1,
input [31:0] reg_rs2,
input [31:0] ex_mem_result,
input [31:0] mem_wb_result,
input [1:0] forward_a,
input [1:0] forward_b,
input [3:0] alu_op,
output reg [31:0] alu_result
);
case (alu_op)
4'b0000: alu_result = operand_a + operand_b;
4'b0001: alu_result = operand_a - operand_b;
4'b0010: alu_result = operand_a & operand_b;
4'b0011: alu_result = operand_a | operand_b;
default: alu_result = 32'b0;
endcase
end
endmodule
SOLUTION STRATEGY:
1. Use 3 identical logic modules
2. Feed outputs to a majority voter
3. Optionally log faults if any module differs
module tmr_logic (
input [3:0] in,
output reg out,
output reg fault_detected
);
module logic_block (
input [3:0] in,
output out
);
assign out = (in[3] & ~in[2]) | (in[1] ^ in[0]);
endmodule
Excellence in World class
VLSI Training & Placements
+91- 9182280927