0% found this document useful (0 votes)
57 views30 pages

25 Advanced Verilog Projects

Uploaded by

amathya45
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
57 views30 pages

25 Advanced Verilog Projects

Uploaded by

amathya45
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

A PRACTICAL GUIDE FOR RTL DESIGNERS, VLSI

ENTHUSIASTS & INTERVIEW PREPARATION

25 ADVANCED
VERILOG
PROJECTS
COMPLETE CODE | REAL WORLD PROBLEMS | REUSABLE
SNIPPETS | OPTIMIZED FOR FPGA & ASIC

Prasanthi Chanda
Q1. 5-Stage Pipeline Instruction Fetch Stage (IF Stage)
module IF_stage (
input clk,
input reset,
input [31:0] pc_in,
output reg [31:0] pc_out,
output reg [31:0] instruction
);

// Simple Instruction Memory (ROM) - 16 instructions


for demo
reg [31:0] instr_mem [0:15];

initial begin
instr_mem[0] = 32'h00000013; // NOP (addi
x0,x0,0)
instr_mem[1] = 32'h00100093; // addi x1,x0,1
instr_mem[2] = 32'h00200113; // addi x2,x0,2
instr_mem[3] = 32'h00308193; // addi x3,x1,3
instr_mem[4] = 32'h00410213; // addi x4,x2,4
// ... fill rest with NOP
instr_mem[5] = 32'h00000013;
instr_mem[6] = 32'h00000013;
instr_mem[7] = 32'h00000013;
instr_mem[8] = 32'h00000013;
instr_mem[9] = 32'h00000013;
instr_mem[10] = 32'h00000013;
instr_mem[11] = 32'h00000013;
instr_mem[12] = 32'h00000013;
instr_mem[13] = 32'h00000013;
instr_mem[14] = 32'h00000013;
instr_mem[15] = 32'h00000013;
end

always @(posedge clk or posedge reset) begin


if(reset) begin
pc_out <= 32'd0;
instruction <= 32'd0;
end else begin
pc_out <= pc_in + 4;
instruction <= instr_mem[pc_in[5:2]]; // word-
aligned address indexing
end
end
endmodule
Q2. AXI4-Lite Slave Write Channel Basic Implementation
module axi4lite_slave #(
parameter ADDR_WIDTH = 4,
parameter DATA_WIDTH = 32
)(
input wire clk,
input wire resetn,
// Write address channel
input wire [ADDR_WIDTH-1:0] awaddr,
input wire awvalid,
output reg awready,
// Write data channel
input wire [DATA_WIDTH-1:0] wdata,
input wire [(DATA_WIDTH/8)-1:0] wstrb,
input wire wvalid,
output reg wready,
// Write response channel
output reg [1:0] bresp,
output reg bvalid,
input wire bready
);
// 4 registers
reg [DATA_WIDTH-1:0] regs [0:3];
reg aw_handshake;
reg w_handshake;
always @(posedge clk or negedge resetn) begin
if(!resetn) begin
awready <= 0;
wready <= 0;
bvalid <= 0;
bresp <= 2'b00;
aw_handshake <= 0;
w_handshake <= 0;
end else begin

// Address handshake
if(!awready && awvalid)
awready <= 1;
else
awready <= 0;

// Write data handshake


if(!wready && wvalid)
wready <= 1;
else
wready <= 0;
// When both handshake done, write register
aw_handshake <= awready & awvalid;
w_handshake <= wready & wvalid;
if(aw_handshake && w_handshake) begin
if(awaddr[3:2] < 4) begin
// write bytes with strobe
integer i;
for(i=0; i<DATA_WIDTH/8; i=i+1) begin
if(wstrb[i]) begin
regs[awaddr[3:2]][8*i +: 8] <= wdata[8*i +:
8];
end
end
bresp <= 2'b00; // OKAY
end else
bresp <= 2'b10; // SLVERR
bvalid <= 1;
end else if(bvalid && bready) begin
bvalid <= 0;
end
end
end
endmodule
Q3. Triple Modular Redundancy (TMR) Majority Voter
Module
module tmr_majority_voter #(parameter WIDTH = 8)(
input wire [WIDTH-1:0] in1,
input wire [WIDTH-1:0] in2,
input wire [WIDTH-1:0] in3,
output wire [WIDTH-1:0] out
);
assign out = (in1 & in2) | (in2 & in3) | (in1 & in3);
endmodule

Q4. UART Transmitter with Baud Rate Generator (Basic)


module uart_tx #(
parameter CLK_FREQ = 50_000_000,
parameter BAUD_RATE = 115200
)(
input wire clk,
input wire reset,
input wire tx_start,
input wire [7:0] tx_data,
output reg tx,
output reg tx_busy
);
localparam integer BAUD_DIV = CLK_FREQ /
BAUD_RATE;
reg [15:0] baud_cnt = 0;
reg baud_tick = 0;

// Baud rate generator


always @(posedge clk) begin
if(reset) begin
baud_cnt <= 0;
baud_tick <= 0;
end else if(baud_cnt == BAUD_DIV-1) begin
baud_cnt <= 0;
baud_tick <= 1;
end else begin
baud_cnt <= baud_cnt + 1;
baud_tick <= 0;
end
end

// UART TX FSM
reg [3:0] bit_idx = 0;
reg [9:0] shift_reg = 10'b1111111111; // start(0),
data(8), stop(1)
always @(posedge clk) begin
if(reset) begin
tx <= 1;
tx_busy <= 0;
bit_idx <= 0;
shift_reg <= 10'b1111111111;
end else if(baud_tick) begin
if(tx_busy) begin
tx <= shift_reg[0];
shift_reg <= {1'b1, shift_reg[9:1]};
if(bit_idx == 9) begin
tx_busy <= 0;
bit_idx <= 0;
end else
bit_idx <= bit_idx + 1;
end else if(tx_start) begin
shift_reg <= {1'b1, tx_data, 1'b0}; // stop bit =1,
data bits, start bit=0
tx_busy <= 1;
end else
tx <= 1; // idle high
end
end
endmodule
Q5. Power-Efficient Clock Gating Module (Simple
Enable-Based)
module clock_gating (
input clk,
input enable,
output gated_clk
);
reg gated_clk_reg;
always @(posedge clk) begin
gated_clk_reg <= enable;
end
assign gated_clk = clk & gated_clk_reg;
endmodule

Q6. Problem Statement: Synchronous FIFO (First-In-


First-Out) Buffer
module sync_fifo #(
parameter DATA_WIDTH = 8,
parameter DEPTH = 16,
parameter ADDR_WIDTH = 4
)(
input clk,
input reset,
input wr_en,
input rd_en,
input [DATA_WIDTH-1:0] data_in,
output reg [DATA_WIDTH-1:0] data_out,
output reg full,
output reg empty
);
reg [DATA_WIDTH-1:0] mem [0:DEPTH-1];
reg [ADDR_WIDTH-1:0] wr_ptr = 0, rd_ptr = 0;
reg [ADDR_WIDTH:0] count = 0;
always @(posedge clk) begin
if(reset) begin
wr_ptr <= 0; rd_ptr <= 0; count <= 0;
full <= 0; empty <= 1;
end else begin
// Write operation
if(wr_en && !full) begin
mem[wr_ptr] <= data_in;
wr_ptr <= wr_ptr + 1;
count <= count + 1;
end
// Read operation
if(rd_en && !empty) begin
data_out <= mem[rd_ptr];
rd_ptr <= rd_ptr + 1;
count <= count - 1;
end
// Update status flags
full <= (count == DEPTH);
empty <= (count == 0);
end
end

endmodule

Q7. Problem Statement: Parameterized N-bit


Comparator
module comparator #(
parameter WIDTH = 8
)(
input [WIDTH-1:0] a,
input [WIDTH-1:0] b,
output gt,
output eq,
output lt
);
assign gt = (a > b);
assign gt = (a > b);
assign eq = (a == b);
assign lt = (a < b);
endmodule

Q8. Problem Statement: Priority Encoder (4-to-2 bits)


module priority_encoder_4to2 (
input [3:0] in,
output reg [1:0] pos,
output reg valid
);
always @(*) begin
casex(in)
4'b0000: begin pos = 2'b00; valid = 0; end
4'b0001: begin pos = 2'b00; valid = 1; end
4'b001x: begin pos = 2'b01; valid = 1; end
4'b01xx: begin pos = 2'b10; valid = 1; end
4'b1xxx: begin pos = 2'b11; valid = 1; end
default: begin pos = 2'b00; valid = 0; end
endcase
end
endmodule
Q9. Problem Statement: Gray Code Counter (N-bit)
module gray_counter #(
parameter WIDTH = 4
)(
input clk,
input reset,
output reg [WIDTH-1:0] gray
);
reg [WIDTH-1:0] binary;
always @(posedge clk or posedge reset) begin
if(reset) begin
binary <= 0;
gray <= 0;
end else begin
binary <= binary + 1;
gray <= (binary >> 1) ^ binary;
end
end
endmodule

Q10. Problem Statement: Configurable Pulse Width


Modulator (PWM)
module pwm_generator #(
parameter COUNTER_WIDTH = 8
)(
input clk,
input reset,
input [COUNTER_WIDTH-1:0] duty_cycle, // 0 to max
count
input [COUNTER_WIDTH-1:0] period,
output reg pwm_out
);
reg [COUNTER_WIDTH-1:0] counter;
always @(posedge clk or posedge reset) begin
if(reset) begin
counter <= 0;
pwm_out <= 0;
end else begin
if(counter < period)
counter <= counter + 1;
else
counter <= 0;
pwm_out <= (counter < duty_cycle) ? 1'b1 : 1'b0;
end
end
endmodule
Q11. Problem Statement: N-bit Linear Feedback Shift
Register (LFSR)
module lfsr #(
parameter N = 8,
parameter TAP = 8'b10000011
)(
input clk,
input reset,
output reg [N-1:0] out
);
wire feedback = ^(out & TAP);
always @(posedge clk or posedge reset) begin
if (reset)
out <= 8'b1;
else
out <= {out[N-2:0], feedback};
end
endmodule

Q12. Problem Statement: Universal Shift Register (4-


bit)
module universal_shift_reg (
input clk,
input reset,
input [1:0] mode, // 00: hold, 01: right shift, 10: left
shift, 11: parallel load
input [3:0] d,
output reg [3:0] q
);
always @(posedge clk or posedge reset) begin
if(reset)
q <= 4'b0000;
else begin
case(mode)
2'b00: q <= q;
2'b01: q <= {1'b0, q[3:1]};
2'b10: q <= {q[2:0], 1'b0};
2'b11: q <= d;
endcase
end
end
endmodule
Q13. Problem Statement: Clock Divider by N
(parameterizable)
module clock_divider #(
parameter N = 10
)(
input clk,
input reset,
output reg clk_out
);
reg [$clog2(N)-1:0] count;
always @(posedge clk or posedge reset) begin
if(reset) begin
count <= 0;
clk_out <= 0;
end else begin
if(count == (N-1)) begin
count <= 0;
clk_out <= ~clk_out;
end else
count <= count + 1;
end
end
endmodule
Q14. Problem Statement: Sequence Detector (Detects
“1011”)
module seq_detector (
input clk,
input reset,
input in,
output reg detected
);
typedef enum reg [2:0] {S0, S1, S2, S3, S4} state_t;
state_t state;
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= S0;
detected <= 0;
end else begin
case(state)
S0: state <= in ? S1 : S0;
S1: state <= in ? S1 : S2;
S2: state <= in ? S3 : S0;
S3: begin
state <= in ? S4 : S2;
detected <= in;
end
S4: begin
state <= in ? S1 : S2;
detected <= 0;
end
endcase
end
end

endmodule
Q15. Problem Statement: 8-bit Arithmetic Logic Unit
(ALU)
module alu (
input [7:0] a, b,
input [2:0] sel,
output reg [7:0] y
);
always @(*) begin
case(sel)
3'b000: y = a + b;
3'b001: y = a - b;
3'b010: y = a & b;
3'b011: y = a | b;
3'b100: y = a ^ b;
3'b101: y = ~a;
3'b110: y = a << 1;
3'b111: y = a >> 1;
endcase
end
endmodule
Q16. Problem Statement: N-bit Barrel Shifter
module barrel_shifter #(
parameter N = 8
)(
input [N-1:0] data_in,
input [$clog2(N)-1:0] shift_amt,
input dir, // 0 = left, 1 = right
output reg [N-1:0] data_out
);
always @(*) begin
if (dir == 0)
data_out = data_in << shift_amt;
else
data_out = data_in >> shift_amt;
end
endmodule
Q17. Problem Statement: Parity Generator and Checker
module parity_gen_check (
input [7:0] data_in,
input parity_bit, // received parity
output reg parity_gen,
output reg error
);
always @(*) begin
parity_gen = ^data_in; // Even parity
error = (parity_gen != parity_bit);
end
endmodule

Q18. Problem Statement: N-bit Up/Down Counter with


Load and Reset
module up_down_counter #(
parameter N = 8
)(
input clk,
input reset,
input load,
input up_down, // 1 = up, 0 = down
input [N-1:0] load_data,
output reg [N-1:0] count
);
always @(posedge clk or posedge reset) begin
if (reset)
count <= 0;
else if (load)
count <= load_data;
else if (up_down)
count <= count + 1;
else
count <= count - 1;
end
endmodule

Q19. Problem Statement: Pulse Synchronizer Between


Clock Domains
module pulse_synchronizer (
input clk_src,
input pulse_src,
input clk_dst,
output reg pulse_dst
);
reg pulse_meta, pulse_sync1, pulse_sync2;

// Sync to destination clock


always @(posedge clk_dst) begin
pulse_sync1 <= pulse_meta;
pulse_sync2 <= pulse_sync1;
pulse_dst <= pulse_sync1 & ~pulse_sync2;
end
// Meta-stability capture
always @(posedge clk_src)
pulse_meta <= pulse_src;

endmodule

Q20. Problem Statement: 8-bit BCD (Binary-Coded


Decimal) Counter
module bcd_counter (
input clk,
input reset,
output reg [3:0] units,
output reg [3:0] tens
);
always @(posedge clk or posedge reset) begin
if (reset) begin
units <= 0;
tens <= 0;
end else begin
if (units == 9) begin
units <= 0;
if (tens == 9)
tens <= 0;
else
tens <= tens + 1;
end else
units <= units + 1;
end
end
endmodule

Q21. Problem Statement: Priority Encoder (8-to-3)

module priority_encoder (
input [7:0] in,
output reg [2:0] out,
output reg valid
);
always @(*) begin
valid = 1;
casex(in)
8'b1xxxxxxx: out = 3'b111;
8'b01xxxxxx: out = 3'b110;
8'b001xxxxx: out = 3'b101;
8'b0001xxxx: out = 3'b100;
8'b00001xxx: out = 3'b011;
8'b000001xx: out = 3'b010;
8'b0000001x: out = 3'b001;
8'b00000001: out = 3'b000;
default: begin out = 3'b000; valid = 0; end
endcase
end

endmodule

Q22. Problem Statement: Gray Code Counter (4-bit)


module gray_counter (
input clk,
input reset,
output reg [3:0] gray
);
reg [3:0] binary;
always @(posedge clk or posedge reset) begin
if (reset) begin
binary <= 0;
gray <= 0;
end else begin
binary <= binary + 1;
gray <= binary ^ (binary >> 1);
end
end
endmodule
Q23. Problem Statement: Dual-Port RAM (Asynchronous
Write, Synchronous Read)
module dual_port_ram (
input clk,
input [2:0] rd_addr,
input [2:0] wr_addr,
input [7:0] wr_data,
input wr_en,
output reg [7:0] rd_data
);

reg [7:0] mem [7:0];

always @(posedge clk)


rd_data <= mem[rd_addr];

always @(*)
if (wr_en)
mem[wr_addr] = wr_data;

endmodule
Q24. Problem Statement: N-bit Carry-Save Adder (CSA)
module carry_save_adder #(
parameter N = 8
)(
input [N-1:0] a, b, c,
output [N-1:0] sum,
output [N-1:0] carry
);
assign sum = a ^ b ^ c;
assign carry = (a & b) | (b & c) | (c & a);
endmodule
Q25. Problem Statement: Signed Multiplier (4-bit
Booth’s Algorithm)
module booth_multiplier (
input clk,
input start,
input signed [3:0] multiplicand,
input signed [3:0] multiplier,
output reg signed [7:0] product,
output reg done
);
reg signed [7:0] A, S, P;
reg [2:0] count;
always @(posedge clk) begin
if (start) begin
A = {multiplicand, 4'b0000};
S = {-multiplicand, 4'b0000};
P = {4'b0000, multiplier, 1'b0};
count = 4;
done = 0;
end else if (count > 0) begin
case (P[1:0])
2'b01: P = P + A;
2'b10: P = P + S;
endcase
P = P >>> 1;
count = count - 1;
end else begin
product = P[7:0];
done = 1;
end
end

endmodule
Excellence in World class
VLSI Training & Placements

Do follow for updates & enquires

+91- 9182280927

You might also like