Honours Lab Record
Honours Lab Record
Design a very basic digital traffic light simulation using Verilog. Simulate a single-direction traffic
light (e.g., North-South) with a Parameterized fixed cycle of changes (e.g., Green, Red) using
outputs.
Design Code
module TrafficLight #(parameter GREEN_TIME = 5, ORANGE_TIME = 3, RED_TIME = 5) (
input clk,
input reset,
output reg green,
output reg orange,
output reg red
);
reg [3:0] counter;
reg [1:0] state;
always @(posedge clk or posedge reset) begin
if (reset) begin
counter <= 0;
state <= 0;
green <= 1;
orange <= 0;
red <= 0;
end else begin
counter <= counter + 1;
case (state)
0: if (counter == GREEN_TIME) begin
state <= 1;
counter <= 0;
green <= 0;
orange <= 1;
red <= 0;
end
1: if (counter == ORANGE_TIME) begin
state <= 2;
counter <= 0;
green <= 0;
orange <= 0;
red <= 1;
end
2: if (counter == RED_TIME) begin
state <= 0;
counter <= 0;
green <= 1;
orange <= 0;
red <= 0;
end
endcase
end
end
endmodule
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
reset = 1;
#10 reset = 0;
#150 $stop;
end
endmodule
Task 2: Simple Digital Clock
Create a simple digital clock using Verilog. Design a clock that displays hours & minutes (24hrs
pattern)using outputs. Exclude alarm or snooze features.
Design Code:
module DigitalClock (
input clk,
input reset,
output reg [4:0] hours,
output reg [5:0] minutes
);
always @(posedge clk or posedge reset) begin
if (reset) begin
hours <= 0;
minutes <= 0;
end else begin
if (minutes == 59) begin
minutes <= 0;
if (hours == 23) begin
hours <= 0;
end else begin
hours <= hours + 1;
end
end else begin
minutes <= minutes + 1;
end
end
end
endmodule
DigitalClock dut (
.clk(clk),
.reset(reset),
.hours(hours),
.minutes(minutes)};
initial begin
clk = 0;
forever #1 clk = ~clk;
end
initial begin
reset = 1;
#5 reset = 0;
#3000 $stop;
end
endmodule
Task 3: Digital Pattern Display
Develop a basic digital pattern display using Verilog. Simulate a pattern that can be started and
stopped with a button press. The pattern should be displayed on outputs (32bit) and gradually
change in a simple manner.
Design Code:
module DigitalPatternDisplay (
input clk,
input reset,
input start_stop,
output reg [31:0] pattern
);
reg running;
reg [4:0] bit_index;
DigitalPatternDisplay dut (
.clk(clk),
.reset(reset),
.start_stop(start_stop),
.pattern(pattern)
);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
reset = 1;
start_stop = 0;
#10 reset = 0;
#20 start_stop = 1;
#150 start_stop = 0;
#50 start_stop = 1;
#200 $stop;
end
endmodule
Task 4: Basic Countdown Timer (Independent Task)
Create a basic digital countdown timer using Verilog. The timer should display only
minutes & seconds on outputs, allowing users to set a countdown time for either minutes or
seconds.
Design Code:
module CountdownTimer (
input clk,
input reset,
input set_time,
input [5:0] set_minutes,
input [5:0] set_seconds,
output reg [5:0] minutes,
output reg [5:0] seconds,
output reg done
);
reg running;
CountdownTimer dut (
.clk(clk),
.reset(reset),
.set_time(set_time),
.set_minutes(set_minutes),
.set_seconds(set_seconds),
.minutes(minutes),
.seconds(seconds),
.done(done)
);
initial begin
clk = 0;
forever #1 clk = ~clk;
end
initial begin
reset = 1;
set_time = 0;
set_minutes = 0;
set_seconds = 0;
#5 reset = 0;
#5 set_time = 1; set_minutes = 1; set_seconds = 5;
#5 set_time = 0;
#200 $stop;
end
endmodule
Task 5: Simple Coin Toss Simulation
Design a very simple digital coin toss simulation using Verilog. Simulate the tossing of a coin
and display the result (heads or tails) on outputs. The toss can be initiated with a button press.
Simple Coin Toss Simulation:
Design Code:
//This is the design code
module coin_design(button,clk,toss);
input clk;
input button;
output reg toss;
always @(posedge clk)
begin
if(button==1)
begin
toss=$urandom_range(0,1);
end
end
endmodule
Testbench:
`timescale 1ns/1ps
module toss_tb;
reg button;
reg clk;
wire toss;
coin_design uut(button,clk,toss);
initial
begin
clk=0;
button=0;
#3 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#7 button=1;
#3 button=0;
#10 $finish;
end
always
begin
#5 clk=~clk;
end
endmodule
Task 6: Basic Digital Lock
Develop a basic digital lock system using Verilog. Design a module that simulates a door lock
with a fixed code(8bits). Users can enter the code using buttons or switches, and if the correct code is
entered, the lock "opens."
Design Code:
//This is the design code of the lock system
module lock_system(lock,current_pin,input_pin,enter,load);
input [7:0] input_pin;
input [7:0] current_pin;
input enter;
input load;
output reg lock=0;
reg [7:0] set_pin;
always @(posedge load or posedge enter)
begin
if (load && !enter)
begin
// Set the input_pin as the new password
set_pin = input_pin;
lock = 0; // Lock remains closed during the setting of the new password
$display("New password set to %b", set_pin);
end
else if (enter && !load)
begin
// Compare the current_pin with the set_pin
if (current_pin == set_pin)
begin
lock = 1; // Open lock if the entered value matches the password
end
else
begin
lock = 0; // Keep lock closed if the entered value does not match the password
end
end
else
begin
lock = 0; // Keep lock closed otherwise
end
end
endmodule
Testbench:
`timescale 1ns/1ps
module toss_tb;
Testbench:
//This is the testbench of the lock system
`timescale 1ns/1ps
module tb_lock_system;
reg [7:0] input_pin;
reg [7:0] current_pin;
reg enter;
reg load;
wire lock;
// Instantiate the lock_system module
lock_system uut (.input_pin(input_pin),.current_pin(current_pin),.enter(enter),.load(load),
.lock(lock));
initial
begin
// Initialize signals
input_pin = 8'b0;
current_pin = 8'b0;
enter = 0;
load = 0;
// Set a new password
#10 load = 1; enter = 0; input_pin = 8'b10101010; // Set password to 170
#10 load = 0;// Try to unlock with the wrong password
#10 load = 0; enter = 1; current_pin = 8'b11110000; // Attempt with 240
#10 enter = 0;// Try to unlock with the correct password
#10 load = 0; enter = 1; current_pin = 8'b10101010; // Attempt with 170
#10 enter = 0;// Change the password
#10 load = 1; enter = 0; input_pin = 8'b11001100; // Set password to 204
#10 load = 0;// Try to unlock with the old password
#10 load = 0; enter = 1; current_pin = 8'b10101010; // Attempt with 170
#10 enter = 0;// Try to unlock with the new password
#10 load = 0; enter = 1; current_pin = 8'b11001100; // Attempt with 204
#10 enter = 0;// End simulation
#20 $stop;
end
initial
begin
$monitor("At time %t, input_pin = %b, current_pin = %b, enter = %b, load = %b, lock = %b",
$time, input_pin, current_pin, enter, load, lock);
end
endmodule
Task 7: Basic Dice Roll Simulation
Design a basic digital dice roll simulation using Verilog. Simulate the rolling of a six-sided die
and display the result using outputs. No scoring or complex game mechanics are required. The rolling
of die can be initiated with a button press.
Design Code:
//This is the design code
module dice_design(button,dice);
input button;
output reg [2:0]dice;
parameter head=1,tail=0;
always @(button)
begin
if(button==1)
begin
dice=$urandom_range(1,6);
end
else
begin
dice=0;
end
end
endmodule
Testbench:
//This is the testbench(simulation) code for the digital dice
`timescale 1ns/1ps
module design_tb;
reg button;
wire [2:0]dice;
dice_design uut(button,dice);
initial
begin
button=1;
#50 $finish;
end
always #5 button=~button;
endmodule
Task 8: Simple Digital Calculator (Independent Task)
Create a simple digital calculator using Verilog. Implement basic arithmetic operation like addition &
subtraction. The calculator takes user input and displays results using outputs.
Design Code:
//This is the design code of a digital calculator using verilog
module digital_calculator(result,a,b,opt);
input [7:0]a,b;// two 8 bit inputs
input [1:0]opt;
output reg [15:0]result;// one 16 bit output, assuming the multiplcation result is maximum of 16bits
always@(a,b)
begin
case(opt)
2'b00:result=a+b;//addition
2'b01:begin// modulo subtraction |a-b|
if(a>b)
result=a-b;
else
result=b-a;
end
2'b10:result=a*b;//multiplication
2'b11:result=a/b;//divison
endcase
end
endmodule
Testbench:
//This is the testbench for the digital calculator using verilog
`timescale 1ns/1ps
module calculator_tb;
wire [15:0] result;
reg [1:0]opt;
reg[7:0] a,b;
digital_calculator uut(result,a,b,opt);
initial
begin
opt=0;a=8'd24;b=8'd23;
#5 opt=1;a=8'd47;b=8'd23;
#5 opt=1;a=8'd69;b=8'd22;
#5 opt=2;a=8'd72;b=8'd25;
#5 opt=0;a=8'd37;b=8'd19;
#5 opt=1;a=8'd45;b=8'd23;
#5 opt=0;a=8'd24;b=8'd33;
#5 opt=3;a=8'd24;b=8'd2;
#5 $finish;
end
endmodule
Task 9: Binary to Gray Code Converter
Develop a Verilog module for the Binary to Gray Code Converter.
Define inputs (binary) and outputs (Gray code).
Design Code:
//This is the design code of conversion of a binary number to gray code
module binary_to_gray (binary,gray);
parameter w=5;
input [w-1:0]binary;
output reg [w-1:0]gray;
integer i;
always @(*)
begin
gray[w-1] = binary[w-1]; // MSB remains the same
for (i = w-2; i >= 0; i = i - 1)
begin
gray[i] = binary[i+1] ^ binary[i];
end
end
endmodule
Testbench:
`timescale 1ns/1ps
module b_to_g;
parameter w = 5; // Parameter for the width
reg [w-1:0] binary;
wire [w-1:0] gray;
binary_to_gray uut(binary,gray);
initial
begin
binary=5'b10110;
#5 binary=5'b01010;
#5 binary=5'b11100;
#5 binary=5'b10010;
#5 $finish;
end
endmodule
Task 10: Design a digital light intensity display using Verilog.
The module should read light intensity data from a simulated sensor (take this value as input
to the module) and display it on outputs. In this case, the relationship between sensor values and
display values is :
Sensor Values (SV) range from 0 to 255, with 0 representing the lowest light intensity and 255
representing the highest light intensity.
Display Values (DV) are calculated non-linearly to create a more realistic response to light intensity.
The relationship can be described as follows:
DV = (SV^2) / 255
Design Code:
module light_intensity_d(display_value,light_sensor_value);
input [7:0]light_sensor_value;
output reg [7:0]display_value;
always @(light_sensor_value)
begin
if(light_sensor_value==0)
display_value=8'd0;
else
display_value=(light_sensor_value*light_sensor_value)/255;
Testbench:
`timescale 1ns/1ps
module light_intensity_tb;
wire [7:0]display_value;
reg [7:0]light_sensor_value;
light_intensity_d uut(display_value,light_sensor_value);
initial
begin
light_sensor_value=8'd255;
#5 light_sensor_value=8'd40;
#5 light_sensor_value=8'd36;
#5 light_sensor_value=8'd100;
#5 light_sensor_value=8'd23;
#5 light_sensor_value=8'd0;
#5 light_sensor_value=8'd200;
#5 $finish;
end
endmodule
Testbench:
`timescale 1ns/1ps
module bulb_tb;
reg switch1=0,switch2=0;
wire bulb;
lightbulb uut(bulb,switch1,switch2);
initial
begin
repeat(50)
begin
#5
switch1=$urandom_range(0,1);//This function will generate 0 or 1 randomly
switch2=$urandom_range(0,1);
// when switch1 and switch2 will have (0,1) or (1,0) the light bulb will be 1 (on)
end
#10 $finish;
end
endmodule
Task 12: Design a very basic digital temperature display using Verilog.
The module reads temperature data from a simulated sensor (take this value as input to the module)
and displays it on outputs in a simple format. The relationship between the sensor value and
temperature is linear, where:
Sensor Value (SV) ranges from 0 to 255, where 0 represents the lowest temperature, and 255
represents the highest temperature.
Temperature (T) is calculated linearly as follows:
T = SV * 2 - 20 degrees Celsius
The module converts the sensor value to temperature and displays it on the outputs
Design Code:
module temperature_sensor_d(display_value,temp_sensor_value);
input [7:0]temp_sensor_value;
output reg [7:0]display_value;
always @(temp_sensor_value)
begin
if(temp_sensor_value<=0)
display_value=0;
else
display_value=(temp_sensor_value*2)-20;
end
endmodule
Testbench:
`timescale 1ns/1ps
module temp_sensor_tb;
wire [7:0]display_value;
reg [7:0]temp_sensor_value;
temperature_sensor_d(display_value,temp_sensor_value);
initial
begin
temp_sensor_value=8'd255;
#5 temp_sensor_value=8'd40;
#5 temp_sensor_value=8'd36;
#5 temp_sensor_value=8'd100;
#5 temp_sensor_value=8'd23;
#5 temp_sensor_value=8'd0;
#5 temp_sensor_value=8'd200;
#5 $finish;
end
endmodule
Design and simulation of an Asynchronous FIFO:
Design Code:
module AsynchronousFIFO #(parameter DEPTH = 8, WIDTH = 8)(
input wr_clk, // Write clock
input rd_clk, // Read clock
input reset, // Asynchronous reset
input write_enable, // Write enable signal
input read_enable, // Read enable signal
input [WIDTH-1:0] data_in, // Input data
output reg [WIDTH-1:0] data_out, // Output data
output full, // FIFO full flag
output empty // FIFO empty flag
);
reg [WIDTH-1:0] mem [0:DEPTH-1]; // FIFO memory
reg [$clog2(DEPTH):0] write_ptr, read_ptr;
reg [$clog2(DEPTH):0] write_ptr_gray, read_ptr_gray;
reg [$clog2(DEPTH):0] read_ptr_sync, write_ptr_sync;
wire [$clog2(DEPTH):0] next_write_ptr, next_read_ptr;
assign next_write_ptr = (write_ptr + 1) % DEPTH;
assign next_read_ptr = (read_ptr + 1) % DEPTH;
// Gray code conversion
function [$clog2(DEPTH):0] bin_to_gray(input [$clog2(DEPTH):0] bin);
bin_to_gray = bin ^ (bin >> 1);
endfunction
// Synchronize pointers
always @(posedge wr_clk or posedge reset) begin
if (reset) begin
write_ptr <= 0;
write_ptr_gray <= 0;
end else if (write_enable && !full) begin
mem[write_ptr] <= data_in;
write_ptr <= next_write_ptr;
write_ptr_gray <= bin_to_gray(next_write_ptr);
end
end
always @(posedge rd_clk or posedge reset) begin
if (reset) begin
read_ptr <= 0;
read_ptr_gray <= 0;
end else if (read_enable && !empty) begin
data_out <= mem[read_ptr];
read_ptr <= next_read_ptr;
read_ptr_gray <= bin_to_gray(next_read_ptr);
end
end
read_ptr_gray <= bin_to_gray(next_read_ptr);
end
end
// Synchronize pointers between clock domains
always @(posedge wr_clk or posedge reset)
if (reset)
read_ptr_sync <= 0;
else
read_ptr_sync <= read_ptr_gray;
always @(posedge rd_clk or posedge reset)
if (reset)
write_ptr_sync <= 0;
else
write_ptr_sync <= write_ptr_gray;
// Flags
assign full = (next_write_ptr == read_ptr_sync);
assign empty = (write_ptr_sync == read_ptr_gray);
endmodule
Testbench:
module AsynchronousFIFO_TB;
// Parameters
parameter DEPTH = 8;
parameter WIDTH = 8;
// Inputs
reg wr_clk;
reg rd_clk;
reg reset;
reg write_enable;
reg read_enable;
reg [WIDTH-1:0] data_in;
// Outputs
wire [WIDTH-1:0] data_out;
wire full;
wire empty;
// Instantiate the Asynchronous FIFO
AsynchronousFIFO #(DEPTH, WIDTH) fifo (
.wr_clk(wr_clk),
.rd_clk(rd_clk),
.reset(reset),
.write_enable(write_enable),
.read_enable(read_enable),
.data_in(data_in),
.data_out(data_out),
.full(full),
.empty(empty)
.data_in(data_in),
.data_out(data_out),
.full(full),
.empty(empty)
);
// Write and read clock generation
always #7 wr_clk = ~wr_clk; // Write clock with 14ns period
always #5 rd_clk = ~rd_clk; // Read clock with 10ns period
initial begin
// Initialize inputs
wr_clk = 0;
rd_clk = 0;
reset = 1;
write_enable = 0;
read_enable = 0;
data_in = 0
// Reset the FIFO
#15 reset = 0;
// Test write operation
$display("Start writing data...");
repeat (8) begin
@(posedge wr_clk);
write_enable = 1;
data_in = $random % 256; // Random 8-bit data
$display("Written Data: %d, Full: %b", data_in, full);
end
write_enable = 0;
// Test read operation
$display("Start reading data...");
repeat (8) begin
@(posedge rd_clk);
read_enable = 1;
$display("Read Data: %d, Empty: %b", data_out, empty);
end
read_enable = 0;
// End simulation
#20;
$finish;
end
endmodule
Task 14: Design and implement FSM for 10X1 sequence detector (overlapping)
Design Code:
module SequenceDetector(
input clk,
input reset,
input in,
output reg sequence_detected
);
reg [2:0] current_state, next_state;
localparam S0 = 3'b000,
S1 = 3'b001,
S2 = 3'b010,
S3 = 3'b011,
S4 = 3'b100;
SequenceDetector dut (
.clk(clk),
.reset(reset),
.in(in),
.sequence_detected(sequence_detected)
);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
reset = 1; in = 0;
#10 reset = 0;
#10 in = 1; // Start with 1
#10 in = 0; // 10
#10 in = 1; // 101
#10 in = 1; // Overlap: 1011
#10 in = 0; // Start new sequence: 10110
#10 in = 1; // 101101
#10 in = 0;
#10 $stop;
end
endmodule