Verilog Examples

Download as pdf or txt
Download as pdf or txt
You are on page 1of 56

VERILOG

HDL
EXAMPLES
1. 2-DFF Synchronizer.
module dff_sync2(
input clk,
input rst,
input d,
output q_synced
);

reg sync_flop1;
reg sync_flop2;

always @(posedge clk or negedge rst)


begin
if(!rst)
begin
sync_flop1 <= 1'b0;
sync_flop2 <= 1'b0;
end
else begin
sync_flop1 <= d;
sync_flop2 <= sync_flop1;
end
end
assign q_synced = sync_flop2;
endmodule

// Testbench
module dff_sync2_test;

reg clk;
reg rst;
reg d;
wire q_synced;
//wire q;
//wire qb;

// Instantiate design under test


dff_sync2 DFF_SYNC(.clk(clk), .rst(rst),
.d(d), .q_synced(q_synced));

initial begin
clk = 0;
rst = 0;
end

always begin
#5 clk = ~clk;
end

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);
// $display("Reset flop.");
//clk = 0;
//rst = 1;
// d = 1'bx;
// display;

$display("Release reset.");
#5 rst = 1;

display;
#10 d = 1;

//$display("Toggle clk.");
//clk = 1;
//display;
end

task display;
#1 $display("d:%0h, q_synced:%0h",
d, q_synced);
endtask

endmodule

2. FSM Design Techniques with Verilog HDL

Finite State Machine (FSM) Design Techniques

1. Single Process Design

In this approach, a single process is used to code the Present State, Next State, and Output Logic.

module FSM_Type_1_SINGLE_PROCESS (

input clk,
input reset_n,
input i_X1,
output reg o_Out
);

reg [1:0] r_State;

localparam S1 = 2'b00,
S2 = 2'b01,
S3 = 2'b10,
S4 = 2'b11;

always @(posedge clk or posedge reset_n)


begin
if (~reset_n)
begin
r_State <= S1;
o_Out <= 1'b1;
end
else begin
case (r_State)
S1: begin
o_Out <= 1'b1;
if (i_X1 == 1'b1) begin
r_State <= S2;
end
else begin
r_State <= S3;
end
end
S2: begin
r_State <= S4;
o_Out <= 1'b0;
end
S3: begin
r_State <= S4;
o_Out <= 1'b0;
end
S4: begin
r_State <= S1;
o_Out <= 1'b1;
end
endcase
end
end
endmodule

//TESTBENCH
module FSM_Type_1_TB;

reg clk;
reg reset_n;
reg i_X1;
wire o_Out;

//Instantiate the DUT


FSM_Type_1_SINGLE_PROCESS DUT(

.clk (clk),
.reset_n (reset_n),
.i_X1 (i_X1),
.o_Out (o_Out)
);

//Generate a 10ns Clock Signal


always #5 clk = ~clk;

//Initialize & Drive the DUT Signals


initial
begin
clk = 0;
reset_n = 0;
i_X1 = 0;
#3 reset_n = 1;
#6 reset_n = 0;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;

#5 reset_n = 1;
#100 $finish;

end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end
endmodule

2. Two-Process Design

This technique involves using two separate processes: one to code Present State and Next State
logic, and another to code Output Logic.
module FSM_Type_2_TWO_PROCESS (

input clk,
input reset_n,
input i_X1,
output reg o_Out
);

reg [1:0] r_State;

localparam S1 = 2'b00,
S2 = 2'b01,
S3 = 2'b10,
S4 = 2'b11;

always @(posedge clk or posedge reset_n)


begin
if (!reset_n)
r_State <= S1;
else begin
case (r_State)
S1: begin
if (i_X1 == 1'b1)
r_State <= S2;
else
r_State <= S3;
end
S2: r_State <= S4;
S3: r_State <= S4;
S4: r_State <= S1;
endcase
end
end

//Second process to evaluate output logic


always @(r_State) begin
case (r_State)
S1: o_Out = 1'b1;
S2: o_Out = 1'b0;
S3: o_Out = 1'b0;
S4: o_Out = 1'b1;
endcase
end
endmodule

//TESTBENCH
module FSM_Type_2_TB;

reg clk;
reg reset_n;
reg i_X1;
wire o_Out;

//Instantaite the DUT


FSM_Type_2_TWO_PROCESS DUT(

.clk (clk),
.reset_n (reset_n),
.i_X1 (i_x1),
.o_Out (o_Out)
);

//Generate a 10ns Clock Signal


always #5 clk = ~clk;

//Initialize & Drive the DUT Signals


initial
begin
clk = 0;
reset_n = 0;
i_X1 = 0;
#3 reset_n = 1;
#6 reset_n = 0;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;

#5 reset_n = 1;
#100 $finish;

end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end
endmodule

3. Three-Process Design

In this approach, three separate processes are used: one each for Present State, Next State, and
Output Logic.
module FSM_Type_3_THREE_PROCESS (

input clk,
input reset_n,
input i_X1,
output reg o_Out
);

reg [1:0] r_State_P; // Present State


reg [1:0] r_State_N; // Next State

localparam S1 = 2'b00,
S2 = 2'b01,
S3 = 2'b10,
S4 = 2'b11;

// First process to evaluate present state logic


always @(posedge clk or posedge reset_n)
begin
if (~reset_n)
r_State_P <= S1;
else
r_State_P <= r_State_N;
end

// Second process to evaluate next_state logic


always @(r_State_P or i_X1)
begin
case (r_State_P)
S1: begin
if (i_X1 == 1'b1)
r_State_N = S2;
else
r_State_N = S3;
end
S2: r_State_N = S4;
S3: r_State_N = S4;
S4: r_State_N = S1;
endcase
end

//Third process to evaluate output logic


always @(r_State_P) begin
case (r_State_P)
S1: o_Out = 1'b1;
S2: o_Out = 1'b0;
S3: o_Out = 1'b0;
S4: o_Out = 1'b1;
endcase
end
endmodule

//TESTBENCH

module FSM_Type3_TB;

reg clk;
reg reset_n;
reg i_X1;
wire o_Out;

//Instantiate the DUT


FSM_Type_3_THREE_PROCESS DUT(

.clk (clk),
.reset_n (reset_n),
.i_X1 (i_X1),
.o_Out (o_Out)
);

//Generate a 10ns Clock Signal


always #5 clk = ~clk;

//Initialize & Drive the DUT


initial
begin
clk = 0;
reset_n = 0;
i_X1 = 0;
#3 reset_n = 1;
#6 reset_n = 0;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;
@(negedge clk) i_X1 = 0;
@(negedge clk) i_X1 = 1;

#5 reset_n = 1;
#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end
endmodule
3. Generic Pipeline/Repeater Hardware Block.
module generic_pipeline #(
parameter WIDTH = 1,
parameter PIPELINE_STAGE = 1
)(
input i_clk,
input i_rst_n,
input i_en,
input [WIDTH-1:0] i_din,
output [WIDTH-1:0] o_dout
);

// Declarations
reg [(PIPELINE_STAGE+1)*WIDTH-1:0] pipeline;

// Main Body of Code


// The lower WIDTH bits of the pipeline are the input bits
assign pipeline[0 +: WIDTH] = i_din;

// If depth/stages is greater than 0, we create a series of PIPELINE_STAGE


register
// words, each WIDTH bits wide. Data moves through this pipeline one step
// per clock cycle when enable is high
generate
if (PIPELINE_STAGE > 0)
begin : generate_pipeline
always @(posedge i_clk or negedge i_rst_n)
if (!i_rst_n)
pipeline[WIDTH +: (PIPELINE_STAGE*WIDTH)] <= '0;
else
pipeline[WIDTH +: (PIPELINE_STAGE*WIDTH)] <= i_en ? pipeline[0 +:
(PIPELINE_STAGE*WIDTH)]: pipeline[WIDTH +: (PIPELINE_STAGE*WIDTH)];
end : generate_pipeline
endgenerate

// The output is the last stage of the pipeline


assign o_dout = pipeline[PIPELINE_STAGE*WIDTH +: WIDTH];

endmodule // generic_pipeline

// Testbench for Generic Pipeline Module


`timescale 1ns/1ps

module tb_generic_pipeline;

// Parameters
parameter WIDTH = 4;
parameter PIPELINE_STAGE = 2;
parameter CLK_PERIOD = 10;

// Inputs
reg tb_clk;
reg tb_rst_n;
reg tb_en;
reg [WIDTH-1:0] tb_din;
// Outputs
wire [WIDTH-1:0] tb_dout;

// Instantiate the generic_pipeline module


generic_pipeline #(
.WIDTH(WIDTH),
.PIPELINE_STAGE(PIPELINE_STAGE)
) uut (
.i_clk(tb_clk),
.i_rst_n(tb_rst_n),
.i_en(tb_en),
.i_din(tb_din),
.o_dout(tb_dout)
);

// Clock generation
always begin
#((CLK_PERIOD) / 2) tb_clk = ~tb_clk; // Toggle every half period
end

// Initial block for stimulus


initial begin
// Initialize inputs
tb_clk = 0;
tb_rst_n = 1;
tb_en = 1;
tb_din = 8'b1010;

// Apply reset
#10 tb_rst_n = 0;

// Apply some input data


#20 tb_din = 8'b1100;
#30 tb_din = 8'b0011;
#40 tb_din = 8'b1111;

// End simulation
#50 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end
endmodule
4. Simple DFF Synchronous and Asynchronous Design.

//DFF Example with Asynchronous Reset

module dff (

input clk,
input rst,
input d,
output reg q,
output qb);

assign qb = ~q;

always @(posedge clk or posedge rst)


begin
if (rst) begin
// Asynchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule

// Testbench for DFF with Asynchronous Reset


`timescale 1ns/1ps

module tb_dff_async_reset;

// Inputs
reg tb_clk;
reg tb_rst;
reg tb_d;

// Outputs
wire tb_q;
wire tb_qb;

// Instantiate the DFF module with asynchronous reset


dff uut (
.clk(tb_clk),
.rst(tb_rst),
.d(tb_d),
.q(tb_q),
.qb(tb_qb)
);

// Clock generation
always begin
#5 tb_clk = ~tb_clk; // Toggle every 5 time units
end
// Initial block for stimulus
initial begin
// Initialize inputs
tb_clk = 0;
tb_rst = 0;
tb_d = 0;

// Apply asynchronous reset


#10 tb_rst = 1;
#15 tb_rst = 0;
// Apply some input data
#20 tb_d = 1;
#30 tb_d = 0;

// End simulation
#40 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end
endmodule

//DFF Example with Synchronous Reset

module dff (

input clk,
input rst,
input d,
output reg q,
output qb);

assign qb = ~q;

always @(posedge clk )


begin
if (rst) begin
// Synchronous reset when reset goes high
q <= 1'b0;
end else begin
// Assign D to Q on positive clock edge
q <= d;
end
end
endmodule

// Testbench for DFF with Synchronous Reset


`timescale 1ns/1ps

module tb_dff_sync_reset;
// Inputs
reg tb_clk;
reg tb_rst;
reg tb_d;

// Outputs
wire tb_q;
wire tb_qb;

// Instantiate the DFF module with synchronous reset


dff uut (
.clk(tb_clk),
.rst(tb_rst),
.d(tb_d),
.q(tb_q),
.qb(tb_qb)
);

// Clock generation
always begin
#5 tb_clk = ~tb_clk; // Toggle every 5 time units
end

// Initial block for stimulus


initial begin
// Initialize inputs
tb_clk = 0;
tb_rst = 0;
tb_d = 0;

// Apply synchronous reset


#10 tb_rst = 1;
#15 tb_rst = 0;

// Apply some input data


#20 tb_d = 1;
#30 tb_d = 0;

// End simulation
#40 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars();
end

endmodule
5. Mod-M Counter Design with a Tick Generated.
// Design of a Mod-M counter which generates a 1 clock cycyle pulse as well
when count reaches to M

module modMCounter#(parameter M = 5, // count from 0 to M-1

N = 3 // N bits required to count upto M i.e. 2**N >= M

)(
input clk,
input rst,
output complete_tick,
output [N-1:0] count
);

reg [N-1:0] count_reg;


wire[N-1:0] count_next;

always @(posedge clk, posedge rst)


begin
if (rst)
count_reg <= 0;
else
count_reg <= count_next;
end

// set count_next to 0 when maximum count is reached i.e. (M-1)


// otherwise increase the count
assign count_next = (count_reg == M-1) ? 0 : count_reg + 1 ;

//Generate 'tick' on each maximum count


assign complete_tick = (count_reg == M-1) ? 1 : 0;
assign count = count_reg; // assign count to output port

endmodule

// Testbench for modMCounter Module

module mod_M_Counter;
reg clk;
reg rst;
wire complete_tick;
wire [2:0]count;

// Instantiate design under test


modMCounter#(5,3) mode_M_Counter(.clk(clk), .rst(rst),
.complete_tick(complete_tick), .count(count));

initial begin
clk = 0;
rst = 0;
end

always begin
#5 clk = ~clk;
end

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);
$display("Reset flop.");

rst = 1;

$display("Release reset.");

#5 rst = 0;

display;
end

task display;

#1 $display("complete_tick:%0h, count:%0h", complete_tick, count);


#100 $finish;
endtask

endmodule

6. Clock Pulse Generator.


// Clock Pulse Generater
// M = 5000000, N = 23 for 0.1 s
// M = 50000000, N = 26 for 1 s
// M = 500000000, N = 29 for 10 s
module clockTick#(parameter M = 5, // generate ticks after M clock cycle
N = 3 // N bits required to count upto M i.e.
2**N >= M
)(
input clk,
input rst,
output clkPulse
);
modMCounter #(.M(M), .N(N)) clockPulse5cycle (.clk(clk), .rst(rst),
.complete_tick(clkPulse));

endmodule

module modMCounter#(parameter M = 5, // count from 0 to M-1


N = 3 // N bits required to count upto M i.e.
2**N >= M
)(
input clk,
input rst,
output complete_tick,
output [N-1:0] count
);
reg [N-1:0] count_reg;
wire[N-1:0] count_next;

always @(posedge clk, posedge rst)


begin
if (rst)
count_reg <= 0;
else
count_reg <= count_next;
end

// set count_next to 0 when maximum count is reached i.e. (M-1)


// otherwise increase the count
assign count_next = (count_reg == M-1) ? 0 : count_reg + 1 ;

//Generate 'tick' on each maximum count


assign complete_tick = (count_reg == M-1) ? 1 : 0;
assign count = count_reg; // assign count to output port

endmodule

//Testbench
module clockPulsetest;

reg clk;
reg rst;
wire clkPulse;

// Instantiate design under test


clockTick#(16,4) clkPulseGenerator(.clk(clk), .rst(rst),
.clkPulse(clkPulse));

initial begin
clk = 0;
rst = 1;
end

always begin
#5 clk = ~clk;
end

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);
$display("Reset flop.");
display;
rst = 0;

end

task display;
#1 $display("clkPulse:%0h", clkPulse);
#100 $finish;
endtask
endmodule
7. Design of Fixed Priority Arbiter.
module fixed_priority_arbiter(
input clk,
input rst,
input [3:0] REQ,
output reg [3:0] GNT
);

always @ (posedge clk or negedge rst)


begin
if(!rst)
GNT <= 4'b0000;

else if(REQ[3])
GNT <= 4'b1000;

else if(REQ[2])
GNT <= 4'b0100;

else if (REQ[1])
GNT <= 4'b0010;

else if(REQ[0])
GNT <= 4'b0001;

else
GNT <= 4'b0000;

end
endmodule

// TESTBENCH

module fixed_priority_Arbiter_test;
reg clk;
reg rst;
reg [3:0] REQ;
wire [3:0] GNT;

//Instantiate Design Under Test

fixed_priority_arbiter DUT(.clk(clk), .rst(rst), .REQ(REQ), .GNT(GNT));

//Generate a 10 ns Time Period Clock


always #5 clk = ~clk;

//Drive the DUT or Generate stimuli for the DUT

initial begin
clk = 0;
rst = 1;
REQ = 4'b0;
// Assert the Asynchronous Reset after 1 clock period
#10 rst = 0;
//Deassert the Reset
#5 rst = 1;

@(negedge clk) REQ = 4'b1000;

@(negedge clk) REQ = 4'b1010;

@(negedge clk) REQ = 4'b0010;

@(negedge clk) REQ = 4'b0110;

@(negedge clk) REQ = 4'b1110;

@(negedge clk) REQ = 4'b1111;

@(negedge clk) REQ = 4'b0100;

@(negedge clk) REQ = 4'b0010;

#5 rst = 0;

#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end

endmodule

8. Design of Round Robin Arbiter (with Fixed Time Slices).

module round_robin_arbiter_fixed_time_slices(
input clk,
input rst,
input [3:0] REQ,
output reg [3:0] GNT
);

reg [2:0] present_state;


reg [2:0] next_state;
parameter [2:0] S_ideal = 3'b000;
parameter [2:0] S_0 = 3'b001;
parameter [2:0] S_1 = 3'b010;
parameter [2:0] S_2 = 3'b011;
parameter [2:0] S_3 = 3'b100;

always@(posedge clk or negedge rst) // State Register , Sequential always


block
begin
if(!rst)
present_state <= S_ideal;
else
present_state <= next_state;

end

always @(present_state or REQ ) // Next State , Combinational always block


begin
case(present_state)
S_ideal : begin

if(REQ[0])
begin
next_state = S_0;
end

else if(REQ[1])
begin
next_state = S_1;
end

else if(REQ[2])
begin
next_state = S_2;
end

else if(REQ[3])
begin
next_state = S_3;
end

else
begin
next_state = S_ideal;
end
end // S_ideal

S_0 : begin
if(REQ[1])
begin
next_state = S_1;
end
else if(REQ[2])
begin
next_state = S_2;
end

else if(REQ[3])
begin
next_state = S_3;
end

else if(REQ[0])
begin
next_state = S_0;
end

else
begin
next_state = S_ideal;
end
end // S_0

S_1 : begin
if(REQ[2])
begin
next_state = S_2;
end

else if(REQ[3])
begin
next_state = S_3;
end

else if(REQ[0])
begin
next_state = S_0;
end

else if(REQ[1])
begin
next_state = S_1;
end

else
begin
next_state = S_ideal;
end
end //S_1

S_2 : begin
if(REQ[3])
begin
next_state = S_3;
end

else if(REQ[0])
begin
next_state = S_0;
end

else if(REQ[1])
begin
next_state = S_1;
end

else if(REQ[2])
begin
next_state = S_2;
end

else
begin
next_state = S_ideal;
end
end // S_2

S_3 : begin
if(REQ[0])
begin
next_state = S_0;
end

else if(REQ[1])
begin
next_state = S_1;
end

else if(REQ[2])
begin
next_state = S_2;
end

else if(REQ[3])
begin
next_state = S_3;
end

else
begin
next_state = S_ideal;
end
end // S_3

default : begin
if(REQ[0])
begin
next_state = S_0;
end

else if(REQ[1])
begin
next_state = S_1;
end

else if(REQ[2])
begin
next_state = S_2;
end

else if(REQ[3])
begin
next_state = S_3;
end

else
begin
next_state = S_ideal;
end
end // default
endcase // case(state)
end
always @(present_state or next_state) // Output , Combinational always block

begin
case(present_state)
S_0 : begin GNT = 4'b0001; end

S_1 : begin GNT = 4'b0010; end

S_2 : begin GNT = 4'b0100; end

S_3 : begin GNT = 4'b1000; end

default : begin GNT = 4'b0000; end

endcase
end
endmodule // Round Robin Arbiter with Fixed Time Slices

/*Note : Other ways to code output logic : -

//1) For a Glitch Free Output

always @(posedge clk or negedge rst)

begin

if(!rst)

GNT <= 4'b0000;

else

case(present_state)

S_0 : begin GNT <= 4'b0001; end

S_1 : begin GNT <= 4'b0010; end

S_2 : begin GNT <= 4'b0100; end

S_3 : begin GNT <= 4'b1000; end

default : begin GNT <= 4'b0000; end

endcase

end

//2) Using direct continuous assignment statements : -

assign GNT = (present_state = = S_0) ? 4'b0001 :

(present_state = = S_1) ? 4'b0010 :

(present_state = = S_2) ? 4'b0100 :


(present_state = = S_3) ? 4'b1000 : 4'b0000;

//3) Output logic can be coded along with the next state , combinational
logic as well

*/

//Test Bench:

module fixed_priority_Arbiter_fixed_time_slices_test;
reg clk;
reg rst;
reg [3:0] REQ;
wire [3:0] GNT;

//Instantiate Design Under Test

round_robin_arbiter_fixed_time_slices DUT(.clk(clk), .rst(rst), .REQ(REQ),


.GNT(GNT));

//Generate a 10 ns Time Period Clock


always #5 clk = ~clk;

//Drive the DUT or Generate stimuli for the DUT


initial begin
clk = 0;
rst = 1;
REQ = 4'b0;
// Assert the Asynchronous Reset after 1 clock period
#10 rst = 0;
//Deassert the Reset
#5 rst = 1;

@(negedge clk) REQ = 4'b1000;


@(negedge clk) REQ = 4'b1010;
@(negedge clk) REQ = 4'b0010;
@(negedge clk) REQ = 4'b0110;
@(negedge clk) REQ = 4'b1110;
@(negedge clk) REQ = 4'b1111;
@(negedge clk) REQ = 4'b0100;
@(negedge clk) REQ = 4'b0010;

#5 rst = 0;
#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
9. Design of Round Robin Arbiter (with Variable Time Slices).
module round_robin_arbiter_variable_time_slices(
input clk,
input rst,
input [3:0] REQ,
output reg [3:0] GNT
);

reg [2:0] present_state;


reg [2:0] next_state;
parameter [2:0] S_ideal = 3'b000;
parameter [2:0] S_0 = 3'b001;
parameter [2:0] S_1 = 3'b010;
parameter [2:0] S_2 = 3'b011;
parameter [2:0] S_3 = 3'b100;

always @(posedge clk or negedge rst) // State Register, Sequential always


block
begin
if (!rst)
present_state <= S_ideal;
else
present_state <= next_state;
end

always @(present_state or REQ) // Next State, Combinational always block


begin
case (present_state)
S_ideal : begin
if (REQ[0])
next_state = S_0;
else if (REQ[1])
next_state = S_1;
else if (REQ[2])
next_state = S_2;
else if (REQ[3])
next_state = S_3;
else
next_state = S_ideal;
end // S_ideal

S_0 : begin
if (REQ[1])
next_state = S_1;
else if (REQ[2])
next_state = S_2;
else if (REQ[3])
next_state = S_3;
else if (REQ[0])
next_state = S_0;
else
next_state = S_ideal;
end // S_0

S_1 : begin
if (REQ[2])
next_state = S_2;
else if (REQ[3])
next_state = S_3;
else if (REQ[0])
next_state = S_0;
else if (REQ[1])
next_state = S_1;
else
next_state = S_ideal;
end // S_1

S_2 : begin
if (REQ[3])
next_state = S_3;
else if (REQ[0])
next_state = S_0;
else if (REQ[1])
next_state = S_1;
else if (REQ[2])
next_state = S_2;
else
next_state = S_ideal;
end // S_2

S_3 : begin
if (REQ[0])
next_state = S_0;
else if (REQ[1])
next_state = S_1;
else if (REQ[2])
next_state = S_2;
else if (REQ[3])
next_state = S_3;
else
next_state = S_ideal;
end // S_3

default : begin
if (REQ[0])
next_state = S_0;
else if (REQ[1])
next_state = S_1;
else if (REQ[2])
next_state = S_2;
else if (REQ[3])
next_state = S_3;
else
next_state = S_ideal;
end // default
endcase // case(state)
end

always @(present_state or next_state) // Output, Combinational always block


begin
case (present_state)
S_0 : GNT = 4'b0001;
S_1 : GNT = 4'b0010;
S_2 : GNT = 4'b0100;
S_3 : GNT = 4'b1000;
default : GNT = 4'b0000;
endcase
end

endmodule // Round Robin Arbiter with Variable Time Slices

// Testbench for round_robin_arbiter_variable_time_slices Module

`timescale 1ns/1ps

module tb_round_robin_arbiter_variable_time_slices;

reg clk;
reg rst;
reg [3:0] REQ;
wire [3:0] GNT;

// Instantiate design under test


round_robin_arbiter_variable_time_slices DUT (
.clk(clk),
.rst(rst),
.REQ(REQ),
.GNT(GNT)
);

initial begin
// Initialize inputs
clk = 0;
rst = 1;
REQ = 4'b0;

// Apply asynchronous reset after 1 clock period


#10 rst = 0;

// Deassert the reset


#5 rst = 1;

// Generate stimuli for the DUT


@(negedge clk) REQ = 4'b1000;
@(negedge clk) REQ = 4'b1010;
@(negedge clk) REQ = 4'b0010;
@(negedge clk) REQ = 4'b0110;
@(negedge clk) REQ = 4'b1110;
@(negedge clk) REQ = 4'b1111;
@(negedge clk) REQ = 4'b0100;
@(negedge clk) REQ = 4'b0010;

// End simulation
#5 $finish;
end

// Clock generation
always #5 clk = ~clk;
initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule

10. Design of 8*3 Priority Encoder Using Different Coding Styles.


//Verilog HDL Code Using Conditional Assignment Statement:
module priority_encoder(
input [7:0] IN,
output [2:0] OUT
);

assign OUT = (IN[7] == 1'b1) ? 3'b111 :


(IN[6] == 1'b1) ? 3'b110 :
(IN[5] == 1'b1) ? 3'b101 :
(IN[4] == 1'b1) ? 3'b100 :
(IN[3] == 1'b1) ? 3'b011 :
(IN[2] == 1'b1) ? 3'b010 :
(IN[1] == 1'b1) ? 3'b001 :
(IN[0] == 1'b1) ? 3'b000 : 3'bxxx;

endmodule

//TestBench

module priority_encoder_test;
reg [7:0] IN;
wire [2:0] OUT;

// Instantiate design under test


priority_encoder DUT(.IN(IN), .OUT(OUT));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

IN = 8'h0;
#10 IN = 8'b0001_0001;
#10 IN = 8'b1001_0001;
#10 IN = 8'b0000_1001;
#10 IN = 8'b0101_0000;
#10 IN = 8'b0000_1010;
#10 IN = 8'b0101_0101;
#10 IN = 8'b0001_0001;
#10 IN = 8'b0000_1001;
#10 IN = 8'b0001_0101;
#10 IN = 8'b0001_0011;
end
endmodule
//Priority Encoder Using case Statement

module priority_encoder(
input [7:0] IN,
output reg [2:0] OUT
);

always @*
begin
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 : OUT = 3'bxxx;


endcase
end
endmodule

//TestBench

module priority_encoder_test;
reg [7:0] IN;
wire [2:0] OUT;

// Instantiate design under test


priority_encoder DUT(.IN(IN), .OUT(OUT));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

IN = 8'h0;
#10 IN = 8'b0001_0001;
#10 IN = 8'b1001_0001;
#10 IN = 8'b0000_1001;
#10 IN = 8'b0101_0000;
#10 IN = 8'b0000_1010;
#10 IN = 8'b0101_0101;
#10 IN = 8'b0001_0001;
#10 IN = 8'b0000_1001;
#10 IN = 8'b0001_0101;
#10 IN = 8'b0001_0011;
end
endmodule
11. Design of Ring Counter.
module straight_ring_counter #(parameter WIDTH = 4)
(
input clk,
input rst,
output reg [WIDTH-1 : 0] out
);

integer i;
always @(posedge clk or negedge rst)
begin
if(!rst)
out <= 4'h1;
else
begin
out[WIDTH-1] <= out[0];

for(i = 0; i < WIDTH-1; i = i+1 )


begin
out[i] <= out[i+1];
end
end
end
endmodule

//TestBench
module ring_counter_test;
reg clk;
reg rst;
wire [3:0] out;

//Instantiate Design Under Test


straight_ring_counter #(4) DUT(.clk(clk), .rst(rst), .out(out));

//Generate a 10 ns Time Period Clock


always #5 clk = ~clk;

//Drive the DUT or Generate stimuli for the DUT


initial begin
clk = 0;
rst = 1;
// Assert the Asynchronous Reset after 1 clock period
#1 rst = 0;
//Deassert the Reset
#5 rst = 1;

#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
12. Design of Johnson Ring Counter.
module johnson_ring_counter #(parameter WIDTH = 4)
(
input clk,
input rst,
output reg [WIDTH-1 : 0] out
);
integer i;

always@(posedge clk or negedge rst)


begin
if (!rst)
out <= 4'h0;
else

begin
out[WIDTH-1] <= ~ out[0];
for (i =0; i < WIDTH-1; i = i+1)
begin
out[i] <= out[i+1];
end
end
end
endmodule

//Test Bench:

module johnson_counter_test;
reg clk;
reg rst;
wire [3:0] out;

//Instantiate Design Under Test


johnson_ring_counter #(4) DUT(.clk(clk), .rst(rst), .out(out));

//Generate a 10 ns Time Period Clock


always #5 clk = ~clk;

//Drive the DUT or Generate stimuli for the DUT


initial begin
clk = 0;
rst = 1;
// Assert the Asynchronous Reset after 1 clock period
#1 rst = 0;
//Deassert the Reset
#5 rst = 1;

#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
13. Design of an Event Detector.
module pos_edge_det (
input sig, // Input signal for which a positive edge has to be detected
input clk, // Input clock signal
output reg pe // Output signal that gives a pulse when a positive edge
occurs
);

reg sig_dly; // Internal signal to store the delayed version of the signal

// This always block ensures that sig_dly is exactly 1 clock behind sig
always @(posedge clk) begin
sig_dly <= sig;
end

// Combinational logic where sig is AND with delayed, inverted version of sig
// Assign statement assigns the evaluated expression in the RHS to the
internal net pe
assign pe = sig & ~sig_dly;

endmodule

//TestBench
module tb;
reg sig; // Declare internal TB signal called sig to drive the sig pin of
the design
reg clk; // Declare internal TB signal called clk to drive the clock to
the design

// Instantiate the design in TB and connect with signals in TB


pos_edge_det ped0 (
.sig(sig),
.clk(clk),
.pe(pe)
);
// Generate a clock of 100MHz
always #5 clk = ~clk;

// Drive stimulus to the design


initial begin
clk <= 0;
sig <= 0;
#15 sig <= 1;
#20 sig <= 0;
#15 sig <= 1;
#10 sig <= 0;
#20 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
14. Design of an Event Detector.
// Module Event Detector (without input data sync in)

module event_detector_async(
input clk,
input rst,
input data_in,
output event_out
);

reg q_ff;

always @(posedge clk or negedge rst) // Register the data_in


begin
if(!rst)
q_ff <= 1'b0;
else
q_ff <= data_in;
end
assign event_out = (data_in) ^ (q_ff); // event_out Generation
endmodule

//TestBench

module async_event_detectotr_test;
reg clk;
reg rst;
reg data_in;
wire event_out;

//Instantiate Design Under Test

event_detector_async DUT(.clk(clk), .rst(rst), .data_in(data_in),


.event_out(event_out));

//Generate a 10 ns Time Period Clock


always #5 clk = ~clk;

//Drive the DUT or Generate stimuli for the DUT

initial begin
clk = 0;
rst = 1;
data_in = 1'b0;
// Assert the Asynchronous Reset after 1 clock period
#1 rst = 0;
//Deassert the Reset
#5 rst = 1;

@(negedge clk) data_in = 1'b0;

@(negedge clk) data_in = 1'b1;

@(negedge clk) data_in = 1'b1;


@(negedge clk) data_in = 1'b1;

@(negedge clk) data_in = 1'b0;

@(negedge clk) data_in = 1'b0;

@(negedge clk) data_in = 1'b0;

@(negedge clk) data_in = 1'b1;

#100 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end

endmodule

15. Design of Gray Code Counter.


module gray_ctr
# (parameter N = 4)

( input clk,
input rstn,
output reg [N-1:0] out);

reg [N-1:0] q;

always @ (posedge clk) begin


if (!rstn) begin
q <= 0;
out <= 0;
end else begin
q <= q + 1;
`ifdef FOR_LOOP
for (int i = 0; i < N-1; i= i+1) begin
out[i] <= q[i+1] ^ q[i];
end
out[N-1] <= q[N-1];
`else
out <= {q[N-1], q[N-1:1] ^ q[N-2:0]};
`endif
end
end
endmodule

//Testbench
module tb;
parameter N = 4;
reg clk;
reg rstn;
wire [N-1:0] out;

gray_ctr u0 ( .clk(clk),
.rstn(rstn),
.out(out));

always #10 clk = ~clk;

initial begin
{clk, rstn} <= 0;

$monitor ("T=%0t rstn=%0b out=0x%0h", $time, rstn, out);

repeat(2) @ (posedge clk);


rstn <= 1;
repeat(20) @ (posedge clk);
$finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule

16. Design of Synchronous FIFO.


module fifo (
input [7:0] data_in,
input clk,
input rst, rd, wr,
output empty, full,
output reg [3:0] fifo_cnt,
output reg[7:0] data_out
);

reg [7:0] fifo_ram[0:7];


reg [2:0] rd_ptr, wr_ptr;

assign empty = (fifo_cnt == 0);


assign full = (fifo_cnt == 8);

// fifo_ram writing & reading


always @(posedge clk) begin : WRITE
if (wr && !full) begin
fifo_ram[wr_ptr] <= data_in;
wr_ptr <= (wr_ptr == 7) ? 0 : wr_ptr + 1;
end
end

always @(posedge clk) begin : READ


if (rd && !empty) begin
data_out <= fifo_ram[rd_ptr];
rd_ptr <= (rd_ptr == 7) ? 0 : rd_ptr + 1;
end
end

// Pointer Generation
always @(posedge clk) begin : POINTER
if (rst) begin
wr_ptr <= 0;
rd_ptr <= 0;
end
end

// Counter Logic Generation


always @(posedge clk) begin : COUNTER
if (rst) begin
fifo_cnt <= 0;
end
else begin
case ({wr, rd})
2'b00 : fifo_cnt <= fifo_cnt;
2'b01 : fifo_cnt <= (fifo_cnt == 0) ? 0 : fifo_cnt - 1;
2'b10 : fifo_cnt <= (fifo_cnt == 8) ? 8 : fifo_cnt + 1;
2'b11 : fifo_cnt <= fifo_cnt;
default : fifo_cnt <= fifo_cnt;
endcase
end
end

endmodule

//Testbench
`timescale 1ns/1ps

module fifo_tb;

reg [7:0] data_in;


reg clk, rst, rd, wr;
wire empty, full;
reg [3:0] fifo_cnt;
reg [7:0] data_out;

// Instantiate the FIFO module


fifo my_fifo (
.data_in(data_in),
.clk(clk),
.rst(rst),
.rd(rd),
.wr(wr),
.empty(empty),
.full(full),
.fifo_cnt(fifo_cnt),
.data_out(data_out)
);
// Clock generation
initial clk = 0;
always #5 clk = ~clk;

// Reset generation
initial begin
rst = 1;
#10 rst = 0;
end

// Stimulus generation
initial begin
// Test Case 1: Write data to the FIFO
data_in = 8'hAA;
wr = 1;
#20;
wr = 0;

// Test Case 2: Read data from the FIFO


rd = 1;
#20;
rd = 0;

// Print the result


$display("Test Case 2: Read Data = %h", data_out);

// Test Case 3: Write and read data simultaneously


data_in = 8'h55;
wr = 1;
#20;
wr = 0;
rd = 1;
#20;
rd = 0;

// Print the result


$display("Test Case 3: Read Data = %h", data_out);

// Test Case 4: Write more data than the FIFO size


data_in = 8'h11;
wr = 1;
#20;
wr = 1;
#20;
wr = 0;

// Test Case 5: Read from an empty FIFO


rd = 1;
#20;
rd = 0;

// Print the result


$display("Test Case 5: Read Data = %h", data_out);

// Add more test cases as needed

// Finish simulation
#50 $finish;
end

initial begin
// below two lines are used to show waveform
$dumpfile("dump.vcd");
$dumpvars(1);
end

endmodule

17. Design of Simple RAM (Random Access Memory).


module simple_ram #(parameter DATA_WIDTH = 16,
parameter ADDRESS_WIDTH = 4,
parameter ADDRESS_MAX = 16 //2^ADDRESS_WIDTH
)(

// Reset Sigal
input rst,

//Write Port SIgnals


input wr_clk,
input [ADDRESS_WIDTH-1 :0] wr_address,
input [DATA_WIDTH-1 :0] wr_data,
input wr_enable,

//Read Port Signals


input rd_clk,
input [ADDRESS_WIDTH-1 : 0] rd_address,
output reg [DATA_WIDTH-1 :0] rd_data
);

// Memory as multi-dimensional array


reg [DATA_WIDTH-1:0] memory [ADDRESS_MAX-1:0];
integer i;

//Initialize RAM memory


always @ (rst)
begin
if(rst)
begin
for(i = 0; i < ADDRESS_MAX; i = i +1)
begin
memory[i] = 16'h0;
end
end
end

// Write data to memory


always @(posedge wr_clk) begin
if (wr_enable) begin
memory[wr_address] <= wr_data;
end
end

// Read data from memory


always @(posedge rd_clk) begin
rd_data <= memory[rd_address];
end
endmodule

//TestBench:
module simple_ram_test;
reg rst;
reg wr_clk;
reg [4:0] wr_address;
reg [7:0] wr_data;
reg wr_enable;
reg rd_clk;
reg [4:0] rd_address;
wire [7:0] rd_data;

//Instantiate Design Under Test


simple_ram #(8, 5, 32) RAM (
.wr_clk(wr_clk),
.wr_address(wr_address),
.wr_data(wr_data),
.wr_enable(wr_enable),
.rd_clk(rd_clk),
.rd_address(rd_address),
.rd_data(rd_data));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);
rst = 0;
#5 rst = 1;
#5 rst = 0;
wr_clk = 0;
rd_clk = 0;
wr_enable = 0;
rd_address = 5'hAA;
wr_address = rd_address;
$display("Read initial data.");

toggle_rd_clk;
$display("data[%0h]: %0h",

rd_address, rd_data);
$display("Write new data.");

wr_enable = 1;
wr_data = 8'hBB;
toggle_wr_clk;
wr_enable = 0;
$display("Read new data.");
toggle_rd_clk;
$display("data[%0h]: %0h",
rd_address, rd_data);

rst = 1;
#5 rst = 0;

end

task toggle_wr_clk;
begin
#10 wr_clk = ~wr_clk;
#10 wr_clk = ~wr_clk;
end
endtask

task toggle_rd_clk;
begin
#10 rd_clk = ~rd_clk;
#10 rd_clk = ~rd_clk;
end
endtask

endmodule

18. Verilog HDL Design of a Bi Directional Pin/Pad.


module bidirec (oe, clk, inp, outp, bidir);

// Port Declaration
input oe;
input clk;
input [7:0] inp;
output [7:0] outp;
inout [7:0] bidir;

reg [7:0] a;
reg [7:0] b;

assign bidir = oe ? a : 8'bZ ;


assign outp = b;

// Always Construct
always @ (posedge clk)
begin
b <= bidir;
a <= inp;
end

endmodule

//Testbench
module tb_bidirec;
reg oe, clk;
reg [7:0] inp;
wire [7:0] outp, bidir;

// Instantiate bidirec module


bidirec my_bidirec (
.oe(oe),
.clk(clk),
.inp(inp),
.outp(outp),
.bidir(bidir)
);

// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk;
end

// Stimulus generation
initial begin
// Enable bidirectional
oe = 1;

// Test Case 1: Write data to bidirectional and read from outp


inp = 8'hAA;
#10;
// Display results
$display("Test Case 1: outp = %h, bidir = %h", outp, bidir);

// Test Case 2: Write different data to bidirectional and read from outp
inp = 8'h55;
#10;
// Display results
$display("Test Case 2: outp = %h, bidir = %h", outp, bidir);

// Test Case 3: Disable bidirectional


oe = 0;
#10;
// Display results
$display("Test Case 3: outp = %h, bidir = %h", outp, bidir);

// Add more test cases as needed


// Finish simulation
#50 $finish;
end

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);
end
endmodule
19. Digital Design of Half Adder (Verilog HDL).
module half_adder(a_in, b_in, sum_o, carry_o);
input a_in;
input b_in;
output sum_o;
output carry_o;
assign sum_o = a_in ^ b_in;
assign carry_o = a_in & b_in;
endmodule

//TestBench
module half_adder_test;

reg a_in;
reg b_in;
wire sum_o;
wire carry_o;

// Instantiate design under test


half_adder DUT(.a_in(a_in), .b_in(b_in), .sum_o(sum_o), .carry_o(carry_o));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 1'b0;
b_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b0;

end

endmodule
20. Digital Design of Full Adder (Verilog HDL).
module full_adder (a_in, b_in, carry_in, sum_o, carry_o);
input a_in;
input b_in;
input carry_in;
output sum_o;
output carry_o;
assign sum_o = (a_in ^ b_in ^ carry_in);
assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));
//assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));
endmodule

//TestBench:

module full_adder_test;
reg a_in;
reg b_in;
reg carry_in;
wire sum_o;
wire carry_o;

// Instantiate design under test


full_adder DUT(.a_in(a_in), .b_in(b_in), .carry_in(carry_in),
.sum_o(sum_o), .carry_o(carry_o));

initial begin

// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 1'b0;
b_in = 1'b0;
carry_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b0; carry_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b1; carry_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b1; carry_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b0; carry_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b0; carry_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b1; carry_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b1; carry_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b0; carry_in = 1'b0;

end

endmodule
21. Digital Design of Half Subtractor (Circuit + Verilog HDL).
module half_subtractor(a_in , b_in , diff_o, borrow_o);
input a_in;
input b_in;
output diff_o;
output borrow_o;

assign diff_o = (a_in ^ b_in);


assign borrow_o = (~a_in & b_in);

endmodule

//TestBench

module half_subtractor_test;
reg a_in;
reg b_in;
wire diff_o;
wire borrow_o;

// Instantiate design under test


half_subtractor DUT(.a_in(a_in), .b_in(b_in), .diff_o(diff_o),
.borrow_o(borrow_o));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 1'b0;
b_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b0;

end

endmodule
22. Digital Design of Full Subtractor (Verilog HDL).
module full_subtractor (a_in, b_in, borrow_in, diff_o, borrow_o);
input a_in;
input b_in;
input borrow_in;
output diff_o;
output borrow_o;

assign diff_o = (a_in ^ b_in ^ borrow_in);


assign borrow_o = ((~(a_in ^ b_in) & borrow_in) | (~a_in & b_in));
//assign borrow_o = ((~a_in & b_in) | (b_in & borrow_in) | (~a_in &
borrow_in));

endmodule

//TestBench
module full_subtractor_test;
reg a_in;
reg b_in;
reg borrow_in;
wire diff_o;
wire borrow_o;

// Instantiate design under test


full_subtractor DUT(.a_in(a_in), .b_in(b_in), .borrow_in(borrow_in),
.diff_o(diff_o), .borrow_o(borrow_o));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 1'b0;
b_in = 1'b0;
borrow_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b0; borrow_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b1; borrow_in = 1'b0;

#10 a_in = 1'b0; b_in = 1'b1; borrow_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b0; borrow_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b0; borrow_in = 1'b1;

#10 a_in = 1'b1; b_in = 1'b1; borrow_in = 1'b0;

#10 a_in = 1'b1; b_in = 1'b1; borrow_in = 1'b1;

#10 a_in = 1'b0; b_in = 1'b0; borrow_in = 1'b0;

end

endmodule
23. Digital Design of Ripple Carry Adder (Verilog HDL).
`include "full_adder.sv"

module ripple_carry_adder(a_in, b_in, carry_in, sum_o, carry_o);


input [3:0] a_in;
input [3:0] b_in;
input carry_in;
output [3:0] sum_o;
output carry_o;
wire carry_1, carry_2, carry_3;

full_adder FA1(.a_in(a_in[0]), .b_in(b_in[0]), .carry_in(carry_in),


.sum_o(sum_o[0]), .carry_o(carry_1));
full_adder FA2(.a_in(a_in[1]), .b_in(b_in[1]), .carry_in(carry_1),
.sum_o(sum_o[1]), .carry_o(carry_2));
full_adder FA3(.a_in(a_in[2]), .b_in(b_in[2]), .carry_in(carry_2),
.sum_o(sum_o[2]), .carry_o(carry_3));
full_adder FA4(.a_in(a_in[3]), .b_in(b_in[3]), .carry_in(carry_3),
.sum_o(sum_o[3]), .carry_o(carry_o));

endmodule

//full_adder.sv
module full_adder (a_in, b_in, carry_in, sum_o, carry_o);
input a_in;
input b_in;
input carry_in;
output sum_o;
output carry_o;

assign sum_o = (a_in ^ b_in ^ carry_in);


assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));
//assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));

endmodule

//TestBench
module ripple_carry_adder_test;
reg [3:0]a_in;
reg [3:0]b_in;
reg carry_in;
wire [3:0]sum_o;
wire carry_o;

// Instantiate design under test


ripple_carry_adder DUT(.a_in(a_in), .b_in(b_in), .carry_in(carry_in),
.sum_o(sum_o), .carry_o(carry_o));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 4'b0000;
b_in = 4'b0000;
carry_in = 1'b0;

#10 a_in = 4'b0000; b_in = 4'b0001; carry_in = 1'b1;

#10 a_in = 4'b0001; b_in = 4'b0001; carry_in = 1'b0;

#10 a_in = 4'b0010; b_in = 4'b0011; carry_in = 1'b1;

#10 a_in = 4'b1111; b_in = 4'b1010; carry_in = 1'b0;

#10 a_in = 4'b1001; b_in = 1'b1000; carry_in = 1'b1;

#10 a_in = 4'b1101; b_in = 4'b1001; carry_in = 1'b0;

#10 a_in = 4'b0001; b_in = 4'b0011; carry_in = 1'b1;

#10 a_in = 4'b0001; b_in = 4'b0000; carry_in = 1'b0;

end

endmodule

24. Digital Design of 4 Bit Carry Lookahead Adder (Verilog HDL).


`include "full_adder.sv"

module carry_look_ahead_adder_4_bit(a_in, b_in, carry_in, sum_o, carry_o);


input [3:0]a_in;
input [3:0]b_in;
input carry_in;
output [3:0]sum_o;
output carry_o;
wire g0, g1, g2, g3; // Carry generate
wire p0, p1, p2, p3; // Carry Propogate
wire c0, c1, c2, c3, c4; // Next step carry
wire c_1, c_2, c_3, c_4;

assign g0 = a_in[0] & b_in[0];


assign g1 = a_in[1] & b_in[1];
assign g2 = a_in[2] & b_in[2];
assign g3 = a_in[3] & b_in[3];
assign p0 = a_in[0] ^ b_in[0];
assign p1 = a_in[1] ^ b_in[1];
assign p2 = a_in[2] ^ b_in[2];
assign p3 = a_in[3] ^ b_in[3];
// C1 = G0 + P0 · C0
// C2 = G1 + P1 · C1 = G1 + P1 · G0 + P1 · P0 · C0
// C3 = G2 + P2 · C2 = G2 + P2 · G1 + P2 · P1 · G0 + P2 · P1 · P0 · C0
// C4 = G3 + P3 · C3 = G3 + P3 · G2 + P3 · P2 · G1 + P3 · P2 · P1 · G0 + P3
· P2 · P1 · P0 · C0

assign c0 = carry_in;
assign c1 = (g0 | (p0 & c0));
assign c2 = (g1 | (p1 & g0) | (p1 & p0 & c0));
assign c3 = (g2 | (p2 & g1) | (p2 & p1 & g0) | (p2 & p1 & p0 & c0));
assign c4 = (g3 | (p3 & g2) | (p3 & p2 & g1) | (p3 & p2 & p1 & g0) | (p3 &
p2 & p1 & p0 & c0));

full_adder FA1(.a_in(a_in[0]), .b_in(b_in[0]), .carry_in(c0),


.sum_o(sum_o[0]), .carry_o(c_1));
full_adder FA2(.a_in(a_in[1]), .b_in(b_in[1]), .carry_in(c1),
.sum_o(sum_o[1]), .carry_o(c_2));
full_adder FA3(.a_in(a_in[2]), .b_in(b_in[2]), .carry_in(c2),
.sum_o(sum_o[2]), .carry_o(c_3));
full_adder FA4(.a_in(a_in[3]), .b_in(b_in[3]), .carry_in(c3),
.sum_o(sum_o[3]), .carry_o(c_4));

assign carry_o = c4;

endmodule

//full_adder.sv
module full_adder (a_in, b_in, carry_in, sum_o, carry_o);
input a_in;
input b_in;
input carry_in;
output sum_o;
output carry_o;

assign sum_o = (a_in ^ b_in ^ carry_in);


assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));
//assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));

endmodule

//TestBench

module carry_look_ahead_adder_4_bit_test;
reg [3:0]a_in;
reg [3:0]b_in;
reg carry_in;
wire [3:0]sum_o;
wire carry_o;

// Instantiate design under test


carry_look_ahead_adder_4_bit DUT(.a_in(a_in), .b_in(b_in),
.carry_in(carry_in), .sum_o(sum_o), .carry_o(carry_o));

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

a_in = 4'b0000;
b_in = 4'b0000;
carry_in = 1'b0;

#10 a_in = 4'b0000; b_in = 4'b0001; carry_in = 1'b1;


#10 a_in = 4'b0001; b_in = 4'b0001; carry_in = 1'b0;

#10 a_in = 4'b0010; b_in = 4'b0011; carry_in = 1'b1;

#10 a_in = 4'b1111; b_in = 4'b1010; carry_in = 1'b0;

#10 a_in = 4'b1001; b_in = 1'b1000; carry_in = 1'b1;

#10 a_in = 4'b1101; b_in = 4'b1001; carry_in = 1'b0;

#10 a_in = 4'b0001; b_in = 4'b0011; carry_in = 1'b1;

#10 a_in = 4'b0001; b_in = 4'b0000; carry_in = 1'b0;

end

endmodule

25. Digital Design of 16 Bit Carry Lookahead Adder (Circuit + Verilog HDL)
`timescale 1ns / 1ps
module carry_look_ahead_16bit(a,b, cin, sum,cout);
input [15:0] a,b;
input cin;
output [15:0] sum;
output cout;
wire c1,c2,c3;

carry_look_ahead_4bit cla1 (.a(a[3:0]), .b(b[3:0]), .cin(cin),


.sum(sum[3:0]), .cout(c1));
carry_look_ahead_4bit cla2 (.a(a[7:4]), .b(b[7:4]), .cin(c1), .sum(sum[7:4]),
.cout(c2));
carry_look_ahead_4bit cla3(.a(a[11:8]), .b(b[11:8]), .cin(c2),
.sum(sum[11:8]), .cout(c3));
carry_look_ahead_4bit cla4(.a(a[15:12]), .b(b[15:12]), .cin(c3),
.sum(sum[15:12]), .cout(cout));

endmodule

//4-bit Carry Look Ahead Adder

module carry_look_ahead_4bit(a,b, cin, sum,cout);


input [3:0] a,b;
input cin;
output [3:0] sum;
output cout;

wire [3:0] p,g,c;

assign p=a^b;//propagate
assign g=a&b; //generate

//carry=gi + Pi.ci
assign c[0]=cin;
assign c[1]= g[0]|(p[0]&c[0]);
assign c[2]= g[1] | (p[1]&g[0]) | p[1]&p[0]&c[0];
assign c[3]= g[2] | (p[2]&g[1]) | p[2]&p[1]&g[0] | p[2]&p[1]&p[0]&c[0];
assign cout= g[3] | (p[3]&g[2]) | p[3]&p[2]&g[1] | p[3]&p[2]&p[1]&g[0] |
p[3]&p[2]&p[1]&p[0]&c[0];
assign sum=p^c;

endmodule

////Testbench
module carry_look_ahead_16bit_tb;
reg [15:0] a,b;
reg cin;
wire [15:0] sum;
wire cout;

carry_look_ahead_16bit uut(.a(a), .b(b),.cin(cin),.sum(sum),.cout(cout));

initial begin
a=0; b=0; cin=0;
#10 a=16'd0; b=16'd0; cin=1'd1;
#10 a=16'd14; b=16'd1; cin=1'd1;
#10 a=16'd5; b=16'd0; cin=1'd0;
#10 a=16'd999; b=16'd0; cin=1'd1;
end
initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

end

initial
$monitor( "A=%d, B=%d, Cin= %d, Sum=%d, Cout=%d", a,b,cin,sum,cout);

endmodule

26. Digital Design of Parallel Adder/Subtractor (Verilog HDL).


`include "full_adder.sv"

module parallel_adder_subtractor(a_in, b_in, control_in, sum_diff_o,


carry_borrow_o);
input [3:0] a_in;
input [3:0] b_in;
input control_in;
output [3:0]sum_diff_o;
output carry_borrow_o;
wire [3:0] b_in_q;
wire carry_borrow_1, carry_borrow_2, carry_borrow_3;
assign b_in_q = b_in ^ ({4{control_in}});
full_adder FA1(.a_in(a_in[0]), .b_in(b_in_q[0]), .carry_in(control_in),
.sum_o(sum_diff_o[0]), .carry_o(carry_1));
full_adder FA2(.a_in(a_in[1]), .b_in(b_in_q[1]), .carry_in(carry_1),
.sum_o(sum_diff_o[1]), .carry_o(carry_2));
full_adder FA3(.a_in(a_in[2]), .b_in(b_in_q[2]), .carry_in(carry_2),
.sum_o(sum_diff_o[2]), .carry_o(carry_3));
full_adder FA4(.a_in(a_in[3]), .b_in(b_in_q[3]), .carry_in(carry_3),
.sum_o(sum_diff_o[3]), .carry_o(carry_borrow_o));

endmodule

//full_adder.sv
module full_adder (a_in, b_in, carry_in, sum_o, carry_o);
input a_in;
input b_in;
input carry_in;
output sum_o;
output carry_o;

assign sum_o = (a_in ^ b_in ^ carry_in);


assign carry_o = (((a_in ^ b_in)& carry_in) | (a_in & b_in));
//assign carry_o = ((a_in & b_in) | (b_in & carry_in) | (a_in & carry_in));

endmodule

//TestBench
module parallel_adder_subtractor_test;

reg [3:0] a_in;


reg [3:0] b_in;
reg control_in;
wire [3:0] sum_diff_o;
wire carry_borrow_o;

// Instantiate design under test


parallel_adder_subtractor DUT(
.a_in(a_in),
.b_in(b_in),
.control_in(control_in),
.sum_diff_o(sum_diff_o),
.carry_borrow_o(carry_borrow_o)
);

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

// Set initial values


a_in = 4'b0000;
b_in = 4'b0000;
control_in = 1'b0;

// Monitor signals
$monitor("Time=%0t a_in=%b b_in=%b control_in=%b sum_diff_o=%b
carry_borrow_o=%b",$time, a_in, b_in, control_in, sum_diff_o,
carry_borrow_o);

// Test cases
#10 a_in = 4'b0000; b_in = 4'b0001; control_in = 1'b1;
#10 a_in = 4'b0001; b_in = 4'b0001; control_in = 1'b0;
#10 a_in = 4'b0010; b_in = 4'b0011; control_in = 1'b1;
#10 a_in = 4'b1111; b_in = 4'b1010; control_in = 1'b0;
#10 a_in = 4'b1001; b_in = 1'b1000; control_in = 1'b1;
#10 a_in = 4'b1101; b_in = 4'b1001; control_in = 1'b0;
#10 a_in = 4'b0001; b_in = 4'b0011; control_in = 1'b1;
#10 a_in = 4'b0001; b_in = 4'b0000; control_in = 1'b0;
#10 $finish;
end

endmodule

27. Digital Design of 1 Bit Magnitude Comparator Type#1 (Verilog HDL).


module magnitude_comparator_1_bit(a_in, b_in, aeqb_o, agb_o, alb_o);

input a_in;
input b_in;
output aeqb_o;
output agb_o;
output alb_o;

assign aeqb_o = ((~a_in & ~b_in) | (a_in & b_in));


assign agb_o = (a_in & ~b_in);
assign alb_o = (~a_in & b_in);

endmodule

//TestBench
module magnitude_comparator_1_bit_test;

reg a_in;
reg b_in;
wire aeqb_o;
wire agb_o;
wire alb_o;

// Instantiate design under test


magnitude_comparator_1_bit DUT(
.a_in(a_in),
.b_in(b_in),
.aeqb_o(aeqb_o),
.agb_o(agb_o),
.alb_o(alb_o)
);

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

// Monitor signals
$monitor("Time=%0t a_in=%b b_in=%b a==b_o=%b a>b_o=%b a<b_o=%b",
$time, a_in, b_in, aeqb_o, agb_o, alb_o);

// Test cases
a_in = 1'b0; b_in = 1'b0;
#10 a_in = 1'b1; b_in = 1'b0;
#10 a_in = 1'b0; b_in = 1'b1;
#10 a_in = 1'b1; b_in = 1'b1;
#10 a_in = 1'b0; b_in = 1'b0;

#10 $finish;
end

endmodule

28. Digital Design of 1 Bit Magnitude Comparator Type#2 (Verilog HDL).


module magnitude_comparator_1_bit_type2(a_in, b_in, aeqb_o, agb_o, alb_o,
aeqb_in, agb_in, alb_in);

input a_in;
input b_in;
output aeqb_o;
output agb_o;
output alb_o;
input aeqb_in;
input agb_in;
input alb_in;

reg aeqb_w, agb_w, alb_w;

always @(*)
begin
if(aeqb_in)
begin
aeqb_w = ((~a_in & ~b_in) | (a_in & b_in));
agb_w = (a_in & ~b_in);
alb_w = (~a_in & b_in);
end

else
begin
aeqb_w = aeqb_in;
agb_w = agb_in;
alb_w = alb_in;
end
end

assign aeqb_o = aeqb_w;


assign agb_o = agb_w;
assign alb_o = alb_w;

endmodule

//TestBench

module magnitude_comparator_1_bit_type2_test;

reg a_in;
reg b_in;
reg aeqb_in;
reg agb_in;
reg alb_in;
wire aeqb_o;
wire agb_o;
wire alb_o;

// Instantiate design under test


magnitude_comparator_1_bit_type2 DUT(
.a_in(a_in),
.b_in(b_in),
.aeqb_in(aeqb_in),
.agb_in(agb_in),
.alb_in(alb_in),
.aeqb_o(aeqb_o),
.agb_o(agb_o),
.alb_o(alb_o)
);

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

// Monitor signals
$monitor("Time=%0t a_in=%b b_in=%b a==b_in=%b a>b_in=%b a<b_in=%b
a==b_o=%b a>b_o=%b a<b_o=%b",
$time, a_in, b_in, aeqb_in, agb_in, alb_in, aeqb_o, agb_o,
alb_o);

// Test cases
a_in = 1'b0; b_in = 1'b0; aeqb_in = 1'b0; agb_in = 1'b0; alb_in = 1'b0;
#10 a_in = 1'b1; b_in = 1'b0;
#10 a_in = 1'b0; b_in = 1'b1;
#10 a_in = 1'b1; b_in = 1'b1;
#10 a_in = 1'b0; b_in = 1'b0;
#5 aeqb_in = 1'b1;
#10 a_in = 1'b1; b_in = 1'b0;
#10 a_in = 1'b0; b_in = 1'b1;
#10 a_in = 1'b1; b_in = 1'b1;
#10 a_in = 1'b0; b_in = 1'b0;

#10 $finish;
end
endmodule
29. Digital Design of N Bit Magnitude Comparator (Verilog HDL).
`include "magnitude_comparator_1_bit_type2.sv"

module magnitude_comparator_n_bit_type2#(parameter N = 4)(a_in, b_in, aeqb_o,


agb_o, alb_o, aeqb_in, agb_in, alb_in);

input [N-1 : 0] a_in;


input [N-1 : 0] b_in;
output aeqb_o;
output agb_o;
output alb_o;
input aeqb_in;
input agb_in;
input alb_in;
genvar gen;
wire [N : 0] aeqb_w;
wire [N : 0] agb_w;
wire [N : 0] alb_w;

assign aeqb_w[0] = aeqb_in;


assign agb_w[0] = agb_in;
assign alb_w[0] = alb_in;

generate
for (gen = 0; gen < N; gen++)
begin
magnitude_comparator_1_bit_type2 CMP(.a_in(a_in[gen]),
.b_in(b_in[gen]), .aeqb_in(aeqb_w[gen]), .agb_in(agb_w[gen]),
.alb_in(alb_w[gen]), .aeqb_o(aeqb_w[gen + 1]), .agb_o(agb_w[gen + 1]),
.alb_o(alb_w[gen + 1]));
end
endgenerate

assign aeqb_o = aeqb_w[N];


assign agb_o = agb_w[N];
assign alb_o = alb_w[N];

endmodule

//magnitude_comparator_1_bit_type2
module magnitude_comparator_1_bit_type2(a_in, b_in, aeqb_o, agb_o, alb_o,
aeqb_in, agb_in, alb_in);
input a_in;
input b_in;
output aeqb_o;
output agb_o;
output alb_o;
input aeqb_in;
input agb_in;
input alb_in;

reg aeqb_w, agb_w, alb_w;

always @(*)
begin
if(aeqb_in)
begin
aeqb_w = ((~a_in & ~b_in) | (a_in & b_in));
agb_w = (a_in & ~b_in);
alb_w = (~a_in & b_in);
end

else
begin
aeqb_w = aeqb_in;
agb_w = agb_in;
alb_w = alb_in;
end
end

assign aeqb_o = aeqb_w;


assign agb_o = agb_w;
assign alb_o = alb_w;

endmodule

//TestBench

module magnitude_comparator_n_bit_type2_test;

parameter N = 4;

reg [N-1 : 0] a_in;


reg [N-1 : 0] b_in;
reg aeqb_in;
reg agb_in;
reg alb_in;
wire aeqb_o;
wire agb_o;
wire alb_o;

// Instantiate design under test


magnitude_comparator_n_bit_type2 #(4) DUT(
.a_in(a_in),
.b_in(b_in),
.aeqb_in(aeqb_in),
.agb_in(agb_in),
.alb_in(alb_in),
.aeqb_o(aeqb_o),
.agb_o(agb_o),
.alb_o(alb_o)
);

initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(1);

// Monitor signals
$monitor("Time=%0t a_in=%b b_in=%b aeqb_in=%b agb_in=%b alb_in=%b
aeqb_o=%b agb_o=%b alb_o=%b",
$time, a_in, b_in, aeqb_in, agb_in, alb_in, aeqb_o, agb_o,
alb_o);

// Test cases
a_in = 4'b0; b_in = 4'b0; aeqb_in = 1'b0; agb_in = 1'b0; alb_in = 1'b0;
#10 a_in = 4'b0001; b_in = 4'b0000;
#10 a_in = 4'b0100; b_in = 4'b1001;
#10 a_in = 4'b1010; b_in = 4'b1000;
#10 a_in = 4'b1110; b_in = 4'b0010;
#5 aeqb_in = 1'b1;
#10 a_in = 4'b0001; b_in = 4'b0000;
#10 a_in = 4'b0100; b_in = 4'b1001;
#10 a_in = 4'b1010; b_in = 4'b1000;
#10 a_in = 4'b1110; b_in = 4'b0010;

#10 $finish;
end

endmodule

You might also like