Skip to content

Instantly share code, notes, and snippets.

@mertalp-ulus
Last active January 7, 2024 19:19
Show Gist options
  • Select an option

  • Save mertalp-ulus/2a3141768dec3d224866f3875beabb9c to your computer and use it in GitHub Desktop.

Select an option

Save mertalp-ulus/2a3141768dec3d224866f3875beabb9c to your computer and use it in GitHub Desktop.
51 Verilog examples for learning purposes
/*
* Do not change Module name
* You can use this website to compile Verilog online: https://www.tutorialspoint.com/compile_verilog_online.php
*/
module main;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
/*
* Project 1: Basic Logic Gates
*/
// Behavioral Approach
module and_gate(input wire a, input wire b, output wire out);
assign out = a & b;
endmodule
module or_gate(input wire a, input wire b, output wire out);
assign out = a | b;
endmodule
module not_gate(input wire a, output wire out);
assign out = ~a;
endmodule
// Structural Approach
module and_gate_structural(input wire a, input wire b, output wire out);
and and_instance_1(out,a,b);
endmodule
module or_gate_structural(input wire a, input wire b, output wire out);
or or_instance_1(out, a,b);
endmodule
module not_gate_structural(input wire a, output wire out);
not not_instance_1(out, a);
endmodule
/*
* Project 2: Multiplexer (MUX)
*/
// Behavioral Approach (2:1)
module mux2to1_behavioral(input wire a, input wire b, input wire sel, output wire out);
assign out = sel ? b : a;
endmodule
// Structural Approach (2:1)
module mux2to1_structural(input wire a, input wire b, input wire sel, output wire out);
wire not_sel, a_and_not_sel, b_and_sel;
not(not_sel, sel);
and(a_and_not_sel, a, not_sel);
and(b_and_sel, b, sel);
or(out, a_and_not_sel, b_and_sel);
endmodule
// Behavioral Approach (4:1)
module mux4to1_behavioral(input wire [3:0] inputs, input wire [1:0] sel, output wire out);
assign out = sel[1] ? (sel[0] ? inputs[3] : inputs[2])
: (sel[0] ? inputs[1] : inputs[0]);
endmodule
// Structural Approach (4:1)
module mux4to1_structural(input wire [3:0] inputs, input wire [1:0] sel, output wire out);
wire out_lower_mux, out_upper_mux;
// Two 2x1 MUXes for the lower and upper inputs
mux2to1_structural lower_mux(inputs[0], inputs[1], sel[0], out_lower_mux);
mux2to1_structural upper_mux(inputs[2], inputs[3], sel[0], out_upper_mux);
// Final 2x1 MUX to select between the lower and upper MUX outputs
mux2to1_structural final_mux(out_lower_mux, out_upper_mux, sel[1], out);
endmodule
/*
* Project 3: Demultiplexer (DEMUX)
*/
// Behavioral Approach (1:2)
module demux1to2_behavioral(input wire in, input wire sel, output wire out1, output wire out2);
assign out1 = sel ? 1'b0 : in;
assign out2 = sel ? in : 1'b0;
endmodule
// Structural Approach (1:2)
module demux1to2_structural(input wire in, input wire sel, output wire out1, output wire out2);
wire not_sel;
not(not_sel, sel);
and(out0, in, not_sel);
and(out1, in, sel);
endmodule
// Behavioral Approach (1:4)
module demux1to4_behavioral(input wire in, input wire [1:0] sel, output wire out1, output wire out2, output wire out3, output wire out4);
assign out1 = (sel == 2'b00) ? in : 1'b0;
assign out2 = (sel == 2'b01) ? in : 1'b0;
assign out3 = (sel == 2'b10) ? in : 1'b0;
assign out4 = (sel == 2'b11) ? in : 1'b0;
endmodule
// Structural Approach (1:4)
module demux1to4_structural(input wire in, input wire [1:0] sel, output wire out1, output wire out2, output wire out3, output wire out4);
wire not_sel0, not_sel1;
not(not_sel0, sel[0]);
not(not_sel1, sel[1]);
and(out1, in, not_sel0, not_sel1);
and(out2, in, not_sel0, sel[1]);
and(out3, in, sel[0], not_sel1);
and(out4, in, sel[0], sel[1]);
endmodule
/*
* Project 4: Generic Parameterized Multiplexer (MUX)
*/
// Behavioral Approach
module parameterized_mux_behavioral #(parameter WIDTH = 2 , SIZE = 1 << WIDTH)
(input wire [SIZE-1:0] in , input wire [WIDTH-1:0] sel , output reg out);
always @(*) begin
for (integer i = 0; i < SIZE; i = i + 1) begin
if (sel == i)
out = in[i];
end
end
endmodule
/*
* Project 5: Generic Parameterized Demultiplexer (DEMUX)
*/
// Behavioral Approach
module parameterized_demux_behavioral #(parameter WIDTH = 2, SIZE = 1 << WIDTH) (
input wire in,
input wire [WIDTH-1:0] sel,
output reg [SIZE-1:0] out
);
always @(*) begin
out = 0; // Default to all zeros
for (integer i = 0; i < SIZE; i = i + 1) begin
if (sel == i)
out[i] = in;
end
end
endmodule
/*
* Project 6: Encoder
*/
// Behavioral Approach
module encoder4to2_behavioral(input wire [3:0] in, output reg [1:0] out);
always @(*) begin
case(in)
4'b0001: out = 2'b00;
4'b0010: out = 2'b01;
4'b0100: out = 2'b10;
4'b1000: out = 2'b11;
default: out = 2'bxx; // Undefined state
endcase
end
endmodule
// Structural Approach
module encoder4to2_structural(input wire [3:0] in, output wire [1:0] out);
or(out[0], in[1], in[3]);
or(out[1], in[2], in[3]);
endmodule
/*
* Project 7: Decoder
*/
// Behavioral Approach
module decoder2to4_behavioral(input wire [1:0] in, output reg [3:0] out);
always @(*) begin
case(in)
2'b00: out = 4'b0001;
2'b01: out = 4'b0010;
2'b10: out = 4'b0100;
2'b11: out = 4'b1000;
default: out = 4'bxxxx; // Undefined state
endcase
end
endmodule
// Structural Approach
module decoder2to4_structural(input wire [1:0] in, output wire [3:0] out);
wire not_in0, not_in1;
not(not_in0, in[0]);
not(not_in1, in[1]);
and(out[0], not_in0, not_in1);
and(out[1], not_in0, in[1]);
and(out[2], in[0], not_in1);
and(out[3], in[0], in[1]);
endmodule
/*
* Project 8: 4-bit Even Parity Generator
*/
// Behavioral Approach
module parity_generator_4_bit_even_behavioral(input wire [3:0] data, output wire parity);
// assign parity = ^data; // shorthand for XORing all bits in data
assign parity = data[0] ^ data[1] ^ data[2] ^ data[3];
endmodule
// Structural Approach
module parity_generator_4_bit_even_structural(input wire [3:0] data, output wire parity);
wire temp1, temp2;
xor (temp1, data[0], data[1]);
xor (temp2, data[2], data[3]);
xor (parity, temp1, temp2);
endmodule
/*
* Project 9: 4-bit Even Parity Checker
*/
// Behavioral Approach
module parity_checker_4_bit_even_behavioral(input wire [3:0] data, input wire parity, output wire error);
// assign error = ^data ^ parity; // shorthand for XORing all bits in data and parity
assign error = data[0] ^ data[1] ^ data[2] ^ data[3] ^ parity;
endmodule
// Structural Approach
module parity_checker_4_bit_even_structural(input wire [3:0] data, input wire parity, output wire error);
wire temp1, temp2, temp3;
xor (temp1, data[0], data[1]);
xor (temp2, data[2], data[3]);
xor (temp3, temp1, temp2);
xor (error, temp3, parity);
endmodule
/*
* Project 10: Half Adder (HA)
*/
// Behavioral Approach
module half_adder_behavioral(input wire a, input wire b, output wire sum, output wire carry);
assign sum = a ^ b;
assign carry = a & b;
endmodule
// Structural Approach
module half_adder_structural(input wire a, input wire b, output wire sum, output wire carry);
xor (sum, a, b); // XOR gate for sum
and (carry, a, b); // AND gate for carry
endmodule
/*
* Project 11: Full Adder (FA)
*/
module full_adder_behavioral(input wire a, input wire b, input wire carry_in, output wire sum, output wire carry_out);
assign sum = a ^ b ^ carry_in; // XOR for sum, considering carry_in
assign carry_out = (a & b) | (b & carry_in) | (carry_in & a); // Combination of AND, OR for carry
endmodule
module full_adder_structural(input wire a, input wire b, input wire carry_in, output wire sum, output wire carry_out);
wire sum_ab, carry_ab, carry_bc, carry_ac;
xor (sum_ab, a, b); // Partial sum without carry_in
xor (sum, sum_ab, carry_in); // Total sum including carry_in
and (carry_ab, a, b); // Carry generated by a and b
and (carry_bc, b, carry_in); // Carry generated by b and carry_in
and (carry_ac, carry_in, a); // Carry generated by carry_in and a
or (carry_out, carry_ab, carry_bc, carry_ac); // Total carry
endmodule
/*
* Project 12: Half Subtractor (HS)
*/
// Behavioral Approach
module half_subtractor_behavioral(input wire a, input wire b, output wire diff, output wire borrow);
assign diff = a ^ b; // XOR for difference
assign borrow = ~a & b; // AND with NOT for borrow
endmodule
// Structural Approach
module half_subtractor_structural(input wire a, input wire b, output wire diff, output wire borrow);
wire not_a;
xor (diff, a, b); // XOR for difference
not (not_a, a); // NOT for borrow
and (borrow, not_a, b); // AND for borrow
endmodule
/*
* Project 13: Full Subtractor (FS)
*/
// Behavioral Approach
module full_subtractor_behavioral(input wire a, input wire b, input wire borrow_in, output wire diff, output wire borrow_out);
assign diff = a ^ b ^ borrow_in; // XOR for difference, considering borrow_in
assign borrow_out = (~a & b) | (~a & borrow_in) | (b & borrow_in); // Combination of AND, OR for borrow
endmodule
// Structural Approach
module full_subtractor_structural(input wire a, input wire b, input wire borrow_in, output wire diff, output wire borrow_out);
wire temp_diff, borrow_ab, borrow_bi, borrow_bb;
xor (temp_diff, a, b); // Partial difference without borrow_in
xor (diff, temp_diff, borrow_in); // Total difference including borrow_in
not (a_not, a); // NOT gate for inverting a
and (borrow_ab, a_not, b); // Borrow generated by a and b
and (borrow_bi, a_not, borrow_in); // Borrow generated by a and borrow_in
and (borrow_bb, b, borrow_in); // Borrow generated by b and borrow_in
or (borrow_out, borrow_ab, borrow_bi, borrow_bb); // Total borrow
endmodule
/*
* Project 14: 4-bit Adder
*/
// Behavioral Approach
module adder4bit_behavioral(input wire [3:0] a, input wire [3:0] b, input wire carry_in, output reg [3:0] sum, output reg carry_out);
always @(*) begin
sum = a + b + carry_in;
carry_out = (a[3] & b[3]) | (a[3] & carry_in) | (b[3] & carry_in);
end
endmodule
// Structural Approach
module adder4bit_structural(input wire [3:0] a, input wire [3:0] b, input wire carry_in, output wire [3:0] sum, output wire carry_out);
wire carry0, carry1, carry2;
full_adder_structural fa0(a[0], b[0], carry_in, sum[0], carry0);
full_adder_structural fa1(a[1], b[1], carry0, sum[1], carry1);
full_adder_structural fa2(a[2], b[2], carry1, sum[2], carry2);
full_adder_structural fa3(a[3], b[3], carry2, sum[3], carry_out);
endmodule
/*
* Project 15: 4-bit Subtractor
*/
// Behavioral Approach
module subtractor4bit_behavioral(input wire [3:0] a, input wire [3:0] b, input wire borrow_in, output reg [3:0] diff, output reg borrow_out);
always @(*) begin
diff = a - b - borrow_in;
borrow_out = (~a[3] & b[3]) | (~a[3] & borrow_in) | (b[3] & borrow_in);
end
endmodule
// Structural Approach
module subtractor4bit_structural(input wire [3:0] a, input wire [3:0] b, input wire borrow_in, output wire [3:0] diff, output wire borrow_out);
wire borrow0, borrow1, borrow2;
full_subtractor_structural fs0(a[0], b[0], borrow_in, diff[0], borrow0);
full_subtractor_structural fs1(a[1], b[1], borrow0, diff[1], borrow1);
full_subtractor_structural fs2(a[2], b[2], borrow1, diff[2], borrow2);
full_subtractor_structural fs3(a[3], b[3], borrow2, diff[3], borrow_out);
endmodule
/*
* Project 16: 4-Bit Binary Up Counter
*/
// Behavioral Approach
module counter4bit_behavioral(input wire clk, input wire reset, output reg [3:0] count);
always @(posedge clk or posedge reset) begin
if (reset)
count <= 4'b0000;
else
count <= count + 1;
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 17: 4-Bit Shift Register
*/
// Behavioral Approach
module shift_register4bit_behavioral(input wire clk, input wire reset, input wire [3:0] data_in, input wire shift_left, output reg [3:0] data_out);
always @(posedge clk or posedge reset) begin
if (reset)
data_out <= 4'b0000;
else if (shift_left)
data_out <= data_out << 1; // Shift left
else
data_out <= data_out >> 1; // Shift right
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 18: 4-Bit BCD Adder
*/
// Behavioral Approach
module bcd_adder_behavioral(input wire [3:0] a, input wire [3:0] b, output reg [3:0] sum, output reg carry_out);
wire [4:0] temp_sum; // 5-bit wire to hold the sum including carry
// Step 1: Perform initial addition
assign temp_sum = a + b;
// Step 2: Check and Correct
always @(*) begin
if (temp_sum > 9) begin
sum = temp_sum + 6; // Correct the sum if it exceeds 9
carry_out = 1; // Set carry_out as there is an overflow
end
else begin
sum = temp_sum[3:0]; // No correction needed
carry_out = 0; // No overflow
end
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 19: 4-Bit BCD Subtractor
*/
// Behavioral Approach
module bcd_subtractor_behavioral(input wire [3:0] a, input wire [3:0] b, output reg [3:0] diff, output wire borrow_out);
wire [4:0] temp_diff;
assign temp_diff = a - b; // Subtract the BCD numbers
assign borrow_out = temp_diff[4]; // Borrow out if there is underflow
always @(*) begin
if (borrow_out)
diff = temp_diff + 10; // Correct the difference if there is underflow
else
diff = temp_diff[3:0]; // Assign only the lower 4 bits to diff
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 20: 4-Bit Binary Comparator
*/
// Behavioral Approach
module comparator4bit_behavioral(input wire [3:0] a, input wire [3:0] b, output wire a_gt_b, output wire a_lt_b, output wire a_eq_b);
assign a_gt_b = a > b;
assign a_lt_b = a < b;
assign a_eq_b = a == b;
endmodule
// Structural Approach
module comparator4bit_structural(input wire [3:0] a, input wire [3:0] b, output wire a_gt_b, output wire a_lt_b, output wire a_eq_b);
wire [3:1] gt_intermediate, lt_intermediate, eq_intermediate;
// Most Significant Bit Comparison
assign gt_intermediate[3] = a[3] & ~b[3];
assign lt_intermediate[3] = ~a[3] & b[3];
assign eq_intermediate[3] = a[3] ~^ b[3]; // XNOR for equality
// Bit 2 Comparison
assign gt_intermediate[2] = (eq_intermediate[3]) & (a[2] & ~b[2]);
assign lt_intermediate[2] = (eq_intermediate[3]) & (~a[2] & b[2]);
assign eq_intermediate[2] = eq_intermediate[3] & (a[2] ~^ b[2]);
// Bit 1 Comparison
assign gt_intermediate[1] = (eq_intermediate[2]) & (a[1] & ~b[1]);
assign lt_intermediate[1] = (eq_intermediate[2]) & (~a[1] & b[1]);
assign eq_intermediate[1] = eq_intermediate[2] & (a[1] ~^ b[1]);
// Least Significant Bit Comparison
assign a_gt_b = gt_intermediate[1] | (eq_intermediate[1] & a[0] & ~b[0]);
assign a_lt_b = lt_intermediate[1] | (eq_intermediate[1] & ~a[0] & b[0]);
assign a_eq_b = eq_intermediate[1] & (a[0] ~^ b[0]);
endmodule
/*
* Project 21: 4-Bit Magnitude Comparator
*/
// Behavioral Approach
module magnitude_comparator4bit_behavioral(input wire [3:0] a, input wire [3:0] b, output wire a_gt_b, output wire a_lt_b, output wire a_eq_b);
assign a_gt_b = a > b;
assign a_lt_b = a < b;
assign a_eq_b = a == b;
endmodule
// Structural Approach
module magnitude_comparator4bit_structural(input wire [3:0] a, input wire [3:0] b, output wire a_gt_b, output wire a_lt_b, output wire a_eq_b);
wire [3:0] not_a, not_b;
wire [3:0] a_gt_b_bit, a_lt_b_bit;
wire a_eq_b_all;
// Generate not of inputs
not (not_a[0], a[0]);
not (not_a[1], a[1]);
not (not_a[2], a[2]);
not (not_a[3], a[3]);
not (not_b[0], b[0]);
not (not_b[1], b[1]);
not (not_b[2], b[2]);
not (not_b[3], b[3]);
// Compare each bit
and (a_gt_b_bit[3], a[3], not_b[3]);
and (a_lt_b_bit[3], not_a[3], b[3]);
and (a_gt_b_bit[2], a[2], not_b[2], a_eq_b_all);
and (a_lt_b_bit[2], not_a[2], b[2], a_eq_b_all);
and (a_gt_b_bit[1], a[1], not_b[1], a_eq_b_all);
and (a_lt_b_bit[1], not_a[1], b[1], a_eq_b_all);
and (a_gt_b_bit[0], a[0], not_b[0], a_eq_b_all);
and (a_lt_b_bit[0], not_a[0], b[0], a_eq_b_all);
// Aggregate the results
or (a_gt_b, a_gt_b_bit[0], a_gt_b_bit[1], a_gt_b_bit[2], a_gt_b_bit[3]);
or (a_lt_b, a_lt_b_bit[0], a_lt_b_bit[1], a_lt_b_bit[2], a_lt_b_bit[3]);
nor (a_eq_b, a_gt_b, a_lt_b);
endmodule
/*
* Project 22: 4-Bit Binary to Gray Code Converter
*/
// Behavioral Approach
module binary_to_gray4bit_behavioral(input wire [3:0] binary, output wire [3:0] gray);
assign gray[3] = binary[3]; // MSB is the same
assign gray[2] = binary[3] ^ binary[2];
assign gray[1] = binary[2] ^ binary[1];
assign gray[0] = binary[1] ^ binary[0];
endmodule
// Structural Approach
module binary_to_gray4bit_structural(input wire [3:0] binary, output wire [3:0] gray);
xor (gray[3], binary[3], 1'b0); // MSB is the same
xor (gray[2], binary[3], binary[2]);
xor (gray[1], binary[2], binary[1]);
xor (gray[0], binary[1], binary[0]);
endmodule
/*
* Project 23: 4-Bit Gray Code to Binary Converter
*/
// Behavioral Approach
module gray_to_binary4bit_behavioral(input wire [3:0] gray, output reg [3:0] binary);
always @(*) begin
binary[3] = gray[3];
binary[2] = gray[3] ^ gray[2];
binary[1] = binary[2] ^ gray[1];
binary[0] = binary[1] ^ gray[0];
end
endmodule
// Structural Approach
module gray_to_binary4bit_structural(input wire [3:0] gray, output wire [3:0] binary);
wire temp1, temp2;
assign binary[3] = gray[3];
xor (temp1, gray[3], gray[2]);
assign binary[2] = temp1;
xor (temp2, temp1, gray[1]);
assign binary[1] = temp2;
xor (binary[0], temp2, gray[0]);
endmodule
/*
* Project 24: BCD to 7-Segment Decoder
*/
// Behavioral Approach
module bcd_to_7segment_behavioral(input wire [3:0] bcd, output reg [6:0] display);
// ASCII 7-segment drawing
// _a_
// | |
// f b
// |_g_|
// | |
// e c
// |_d_|
//
// map temp[6:0] to the 7-segment display (a-g)
// a = temp[6]
// b = temp[5]
// c = temp[4]
// d = temp[3]
// e = temp[2]
// f = temp[1]
// g = temp[0]
always @(*) begin
case (bcd)
4'b0000: display = 7'b1111110; // 0
4'b0001: display = 7'b0110000; // 1
4'b0010: display = 7'b1101101; // 2
4'b0011: display = 7'b1111001; // 3
4'b0100: display = 7'b0110011; // 4
4'b0101: display = 7'b1011011; // 5
4'b0110: display = 7'b1011111; // 6
4'b0111: display = 7'b1110000; // 7
4'b1000: display = 7'b1111111; // 8
4'b1001: display = 7'b1111011; // 9
default: display = 7'b0000000;
endcase
end
endmodule
// Structural Approach
module bcd_to_7segment_structural(input wire [3:0] bcd, output wire [6:0] display);
// ASCII 7-segment drawing
// _a_
// | |
// f b
// |_g_|
// | |
// e c
// |_d_|
//
wire [6:0] temp;
// map temp[6:0] to the 7-segment display (a-g)
// a = temp[6]
// b = temp[5]
// c = temp[4]
// d = temp[3]
// e = temp[2]
// f = temp[1]
// g = temp[0]
// 0 => a,b,c,d,e,f
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b1;
assign temp[1] = 1'b1;
assign temp[0] = 1'b0;
assign display = (bcd == 4'b0000) ? temp : 7'b0000000;
// 1 => b,c
assign temp[6] = 1'b0;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b0;
assign temp[2] = 1'b0;
assign temp[1] = 1'b0;
assign temp[0] = 1'b0;
assign display = (bcd == 4'b0001) ? temp : 7'b0000000;
// 2 => a,b,d,e,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b0;
assign temp[3] = 1'b1;
assign temp[2] = 1'b1;
assign temp[1] = 1'b0;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b0010) ? temp : 7'b0000000;
// 3 => a,b,c,d,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b0;
assign temp[1] = 1'b0;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b0011) ? temp : 7'b0000000;
// 4 => b,c,f,g
assign temp[6] = 1'b0;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b0;
assign temp[2] = 1'b0;
assign temp[1] = 1'b1;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b0100) ? temp : 7'b0000000;
// 5 => a,c,d,f,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b0;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b0;
assign temp[1] = 1'b1;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b0101) ? temp : 7'b0000000;
// 6 => a,c,d,e,f,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b0;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b1;
assign temp[1] = 1'b1;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b0110) ? temp : 7'b0000000;
// 7 => a,b,c
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b0;
assign temp[2] = 1'b0;
assign temp[1] = 1'b0;
assign temp[0] = 1'b0;
assign display = (bcd == 4'b0111) ? temp : 7'b0000000;
// 8 => a,b,c,d,e,f,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b1;
assign temp[1] = 1'b1;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b1000) ? temp : 7'b0000000;
// 9 => a,b,c,d,f,g
assign temp[6] = 1'b1;
assign temp[5] = 1'b1;
assign temp[4] = 1'b1;
assign temp[3] = 1'b1;
assign temp[2] = 1'b0;
assign temp[1] = 1'b1;
assign temp[0] = 1'b1;
assign display = (bcd == 4'b1001) ? temp : 7'b0000000;
endmodule
/*
* Project 25: 7-Segment to BCD Encoder
*/
// Behavioral Approach
module segment_to_bcd_behavioral(input wire [6:0] display, output reg [3:0] bcd);
always @(*) begin
case (display)
7'b1111110: bcd = 4'b0000; // 0
7'b0110000: bcd = 4'b0001; // 1
7'b1101101: bcd = 4'b0010; // 2
7'b1111001: bcd = 4'b0011; // 3
7'b0110011: bcd = 4'b0100; // 4
7'b1011011: bcd = 4'b0101; // 5
7'b1011111: bcd = 4'b0110; // 6
7'b1110000: bcd = 4'b0111; // 7
7'b1111111: bcd = 4'b1000; // 8
7'b1111011: bcd = 4'b1001; // 9
default: bcd = 4'bxxxx; // Invalid or undefined pattern
endcase
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 26: Generalized Comparator
*/
// Behavioral Approach
module comparator_generalized #(parameter N = 4) (input wire [N-1:0] a, input wire [N-1:0] b, output wire a_gt_b, output wire a_lt_b, output wire a_eq_b);
assign a_gt_b = a > b;
assign a_lt_b = a < b;
assign a_eq_b = a == b;
endmodule
// Structural Approach
// Not implemented
/*
* Project 27: Finite State Machine (FSM)
*/
// Simple Traffic Light Controller FSM
// Behavioral Approach
module traffic_light_controller(input wire clk, input wire reset, output reg [2:0] light);
// State encoding
parameter GREEN = 3'b001, YELLOW = 3'b010, RED = 3'b100;
// State variable
reg [2:0] state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= RED; // Initial state
else
state <= next_state;
end
// Next state logic
always @(*) begin
case (state)
GREEN: next_state = YELLOW;
YELLOW: next_state = RED;
RED: next_state = GREEN;
default: next_state = RED;
endcase
end
// Output logic
always @(*) begin
case (state)
GREEN: light = GREEN;
YELLOW: light = YELLOW;
RED: light = RED;
default: light = RED;
endcase
end
endmodule
// Enhanced Finite State Machine (FSM): Vending Machine Controller
// Behavioral Approach
module vending_machine_controller(input wire clk, input wire reset, input wire coin1, input wire coin2, output reg dispense_signal);
// State encoding
parameter IDLE = 2'b00, COLLECTING = 2'b01, DISPENSE = 2'b10;
reg [1:0] state, next_state;
reg [2:0] total; // To keep track of the total amount inserted
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= IDLE;
total <= 0;
end
else
state <= next_state;
end
// Next state and total update logic
always @(*) begin
next_state = state;
dispense_signal = 0;
case (state)
IDLE:
if (coin1 || coin2) begin
next_state = COLLECTING;
total = coin1 ? 1 : 2;
end
COLLECTING:
if (coin1 || coin2) begin
total = total + (coin1 ? 1 : 2);
if (total >= 3)
next_state = DISPENSE;
end
DISPENSE:
begin
dispense_signal = 1;
next_state = IDLE;
total = 0;
end
endcase
end
endmodule
/*
* Project 28: Finite State Machines: Mealy and Moore Examples
*/
// Mealy Machine: Output depends on both the current state and the current inputs.
// Moore Machine: Output depends only on the current state.
// Example 1: Mealy Machine
// Behavioral Approach
module mealy_detector(input wire clk, input wire reset, input wire in, output reg out);
// State declaration
reg state, next_state;
parameter S0 = 0, S1 = 1;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= S0;
else
state <= next_state;
end
// Next state and output logic
always @(*) begin
next_state = state;
out = 0;
case (state)
S0: if (in) next_state = S1;
S1: begin
if (!in) out = 1;
next_state = S0;
end
endcase
end
endmodule
// Example 2: Moore Machine
// Behavioral Approach
module moore_detector(input wire clk, input wire reset, input wire in, output reg out);
// State declaration
reg [1:0] state, next_state;
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= S0;
else
state <= next_state;
end
// Next state logic
always @(*) begin
next_state = state;
case (state)
S0: next_state = in ? S1 : S0;
S1: next_state = in ? S2 : S0;
S2: next_state = in ? S2 : S0;
endcase
end
// Output logic
always @(*) begin
out = (state == S2);
end
endmodule
/*
* Project 29: Mealy Finite State Machine (FSM) Real World Example: Password Checker
*/
// Password Checker FSM
// The FSM will check if the input sequence matches a specific password (for simplicity, let's use a 3-digit binary password, say "101"). The FSM will have states representing each correct digit entered and will provide immediate feedback after each input.
// Behavioral Approach
module password_checker_mealy(input wire clk, input wire reset, input wire digit, output reg isMatch);
// State encoding
parameter IDLE = 3'b000, CORRECT1 = 3'b001, CORRECT2 = 3'b010, MATCHED = 3'b011, FAILED = 3'b100;
reg [2:0] state, next_state;
// State transition and output logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
always @(*) begin
isMatch = 0;
case (state)
IDLE:
next_state = (digit == 1'b1) ? CORRECT1 : FAILED;
CORRECT1:
next_state = (digit == 1'b0) ? CORRECT2 : FAILED;
CORRECT2:
begin
next_state = (digit == 1'b1) ? MATCHED : FAILED;
isMatch = (digit == 1'b1) ? 1'b1 : 1'b0;
end
MATCHED:
next_state = IDLE;
FAILED:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
endmodule
/*
* Project 30: Moore Finite State Machine (FSM) Real World Example: Sequence Detector
*/
// Sequence Detector FSM
// The FSM will have states for each step in detecting the sequence "1101". It will provide an output signal when the sequence is completely detected.
// Behavioral Approach
module sequence_detector_moore(input wire clk, input wire reset, input wire bit, output reg sequenceDetected);
// State encoding
parameter IDLE = 4'b0000, DETECT_1 = 4'b0001, DETECT_11 = 4'b0010, DETECT_110 = 4'b0100, SEQUENCE_DETECTED = 4'b1000;
reg [3:0] state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next state logic
always @(*) begin
sequenceDetected = (state == SEQUENCE_DETECTED);
case (state)
IDLE:
next_state = (bit == 1) ? DETECT_1 : IDLE;
DETECT_1:
next_state = (bit == 1) ? DETECT_11 : IDLE;
DETECT_11:
next_state = (bit == 0) ? DETECT_110 : DETECT_1;
DETECT_110:
next_state = (bit == 1) ? SEQUENCE_DETECTED : IDLE;
SEQUENCE_DETECTED:
next_state = IDLE;
default:
next_state = IDLE;
endcase
end
endmodule
/*
* Project 31: Multiplication
*/
// Behavioral Approach
module multiplier4bit_behavioral(input wire [3:0] a, input wire [3:0] b, output wire [7:0] product);
assign product = a * b; // Direct multiplication
endmodule
// Structural Approach
// Not implemented
/*
* Project 32: Division
*/
// Behavioral Approach
module divider4bit_behavioral(input wire [3:0] dividend, input wire [3:0] divisor, output wire [3:0] quotient, output wire [3:0] remainder);
assign quotient = dividend / divisor; // Direct division for quotient
assign remainder = dividend % divisor; // Direct modulus for remainder
endmodule
// Structural Approach
// Not implemented
/*
* Project 33: FSM Calculator
*/
// Behavioral Approach
module fsm_calculator(input wire clk, input wire reset, input wire [3:0] operand1, input wire [3:0] operand2, input wire [1:0] operation, output reg [7:0] result);
reg [2:0] state;
parameter INPUT_CAPTURE = 3'b001, COMPUTE = 3'b010, OUTPUT = 3'b100;
always @(posedge clk or posedge reset) begin
if (reset)
state <= INPUT_CAPTURE;
else begin
case (state)
INPUT_CAPTURE: state <= COMPUTE;
COMPUTE: state <= OUTPUT;
OUTPUT: state <= INPUT_CAPTURE;
default: state <= INPUT_CAPTURE;
endcase
end
end
always @(*) begin
case (state)
COMPUTE: begin
case (operation)
2'b00: result = operand1 + operand2; // Addition
2'b01: result = operand1 - operand2; // Subtraction
2'b10: result = operand1 * operand2; // Multiplication
2'b11: result = operand1 / operand2; // Division
default: result = 8'b00000000;
endcase
end
default: result = 8'b00000000;
endcase
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 34: 4-Bit Barrel Shifter
*/
// Behavioral Approach
module barrel_shifter4bit_behavioral(input wire [3:0] a, input wire [1:0] shift, output wire [3:0] result);
assign result = (shift == 2'b00) ? a : // No shift
(shift == 2'b01) ? {a[2:0], a[3]} : // Shift left by 1
(shift == 2'b10) ? {a[0], a[3:1]} : // Shift right by 1
(shift == 2'b11) ? {a[1:0], a[3:2]} : // Rotate left by 1
4'b0000; // Undefined
endmodule
// Structural Approach
// Not implemented
/*
* Project 35: Basic Memory Module (RAM)
*/
// Behavioral Approach
module ram_module(input wire clk, input wire [3:0] address, input wire [7:0] data_in, input wire write_enable, output reg [7:0] data_out);
reg [7:0] memory [0:15]; // Define a 16x8-bit RAM
always @(posedge clk) begin
if (write_enable)
memory[address] <= data_in; // Write operation
else
data_out <= memory[address]; // Read operation
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 36: Advanced RAM Module
*/
// Behavioral Approach
module advanced_ram(
input wire clk,
input wire read_enable,
input wire write_enable,
input wire [ADDR_WIDTH-1:0] address,
input wire [DATA_WIDTH-1:0] data_in,
input wire [DATA_WIDTH-1:0] write_mask, // Mask for selective bit writing
output reg [DATA_WIDTH-1:0] data_out
);
parameter DATA_WIDTH = 8; // Data size
parameter ADDR_WIDTH = 4; // Address size, defining memory depth
parameter DEPTH = 1 << ADDR_WIDTH; // Memory depth
// Memory array
reg [DATA_WIDTH-1:0] memory [0:DEPTH-1];
always @(posedge clk) begin
if (write_enable) begin
// Masked write operation
// (data_in & write_mask) : Selective bit writing
// (memory[address] & ~write_mask) : Preserve the bits that are not selected for writing
// OR the above two to get the final combined result
memory[address] <= (data_in & write_mask) | (memory[address] & ~write_mask);
end
if (read_enable) begin
// Read operation
data_out <= memory[address];
end
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 37: Advanced RAM Module with OTP XOR Encryption
*/
// Behavioral Approach
module encrypted_ram(
input wire clk,
input wire read_enable,
input wire write_enable,
input wire encrypt_enable, // Enable encryption
input wire [ADDR_WIDTH-1:0] address,
input wire [DATA_WIDTH-1:0] data_in,
input wire [DATA_WIDTH-1:0] key, // OTP key for encryption/decryption
output reg [DATA_WIDTH-1:0] data_out
);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 4;
parameter DEPTH = 1 << ADDR_WIDTH;
reg [DATA_WIDTH-1:0] memory [0:DEPTH-1];
always @(posedge clk) begin
if (write_enable) begin
// Encrypt data if encryption is enabled, otherwise write plain data
memory[address] <= encrypt_enable ? (data_in ^ key) : data_in;
end
if (read_enable) begin
// Decrypt data if encryption is enabled, otherwise read plain data
data_out <= encrypt_enable ? (memory[address] ^ key) : memory[address];
end
end
endmodule
// Structural Approach
// Not implemented
/*
* Project 38: Traffic Light Controller with Pedestrian Crossing (FSM & Interrupt Example)
*/
// Behavioral Approach
module traffic_light_controller_with_interrupt(
input wire clk,
input wire reset,
input wire pedestrian_button, // Pedestrian crossing button (interrupt)
output reg [2:0] traffic_light, // Traffic light output
output reg pedestrian_cross_signal // Signal for pedestrian crossing
);
// State encoding
parameter GREEN = 3'b001, YELLOW = 3'b010, RED = 3'b100, PEDESTRIAN_CROSS = 3'b101;
reg [2:0] state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= RED;
else
state <= next_state;
end
// Next state logic with interrupt handling
always @(*) begin
case (state)
GREEN: next_state = pedestrian_button ? PEDESTRIAN_CROSS : YELLOW;
YELLOW: next_state = pedestrian_button ? PEDESTRIAN_CROSS : RED;
RED: next_state = pedestrian_button ? PEDESTRIAN_CROSS : GREEN;
PEDESTRIAN_CROSS: next_state = RED; // After pedestrian crossing, go to RED
default: next_state = RED;
endcase
end
// Output logic
always @(*) begin
case (state)
GREEN: begin
traffic_light = GREEN;
pedestrian_cross_signal = 0;
end
YELLOW: begin
traffic_light = YELLOW;
pedestrian_cross_signal = 0;
end
RED, PEDESTRIAN_CROSS: begin
traffic_light = RED;
pedestrian_cross_signal = 1; // Enable crossing signal in RED and PEDESTRIAN_CROSS states
end
default: begin
traffic_light = RED;
pedestrian_cross_signal = 0;
end
endcase
end
endmodule
/*
* Project 39: Elevator Control System with Emergency Stop (FSM & Interrupt Example)
*/
// Behavioral Approach
module elevator_control_system(
input wire clk,
input wire reset,
input wire emergency_stop, // Emergency stop button (interrupt)
input wire request_first_floor,
input wire request_second_floor,
output reg [1:0] current_floor, // Current floor of the elevator
output reg emergency_active // Signal indicating emergency stop is active
);
// State encoding
parameter IDLE = 2'b00, MOVING_TO_FIRST = 2'b01, MOVING_TO_SECOND = 2'b10, EMERGENCY_STOP = 2'b11;
reg [1:0] state, next_state;
// State transition logic
always @(posedge clk or posedge reset) begin
if (reset)
state <= IDLE;
else
state <= next_state;
end
// Next state logic with interrupt handling
always @(*) begin
case (state)
IDLE: begin
if (emergency_stop)
next_state = EMERGENCY_STOP;
else if (request_first_floor)
next_state = MOVING_TO_FIRST;
else if (request_second_floor)
next_state = MOVING_TO_SECOND;
else
next_state = IDLE;
end
MOVING_TO_FIRST, MOVING_TO_SECOND: begin
next_state = emergency_stop ? EMERGENCY_STOP : IDLE;
end
EMERGENCY_STOP: begin
next_state = emergency_stop ? EMERGENCY_STOP : IDLE; // Remain in emergency stop until the button is released
end
default: next_state = IDLE;
endcase
end
// Output logic
always @(*) begin
case (state)
IDLE: begin
current_floor = 2'b00; // Ground floor
emergency_active = 0;
end
MOVING_TO_FIRST: begin
current_floor = 2'b01; // First floor
emergency_active = 0;
end
MOVING_TO_SECOND: begin
current_floor = 2'b10; // Second floor
emergency_active = 0;
end
EMERGENCY_STOP: begin
// Keep the current floor unchanged but activate emergency signal
emergency_active = 1;
end
default: begin
current_floor = 2'b00;
emergency_active = 0;
end
endcase
end
endmodule
/*
* Project 40: Advanced FSM Example: Digital Watch with Multiple Modes and Settings
*/
// Behavioral Approach
module digital_watch_fsm(
input wire clk,
input wire reset,
input wire mode_button,
input wire set_button,
input wire adjust_up,
input wire adjust_down,
output reg [3:0] hours,
output reg [3:0] minutes,
output reg alarm_active,
output reg stopwatch_running,
output reg in_setting_mode
);
// State Encoding
parameter TIME_DISPLAY = 2'b00, ALARM = 2'b01, STOPWATCH = 2'b10, SETTINGS = 2'b11;
reg [1:0] state, next_state;
// Sub-state Encoding for Settings
parameter SET_HOURS = 2'b00, SET_MINUTES = 2'b01;
reg [1:0] setting_state, next_setting_state;
// Button Debounce Logic (not implemented, assumed debounced)
wire mode_pressed, set_pressed, adjust_up_pressed, adjust_down_pressed;
// Clock Divider for 1 Hz Clock (not implemented, assumed provided)
wire one_hz_clk;
// Registers for Time, Alarm, Stopwatch
reg [3:0] current_hours, current_minutes;
reg [3:0] alarm_hours, alarm_minutes;
reg [7:0] stopwatch_seconds;
// State Transition Logic
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= TIME_DISPLAY;
setting_state <= SET_HOURS;
end else begin
state <= next_state;
setting_state <= next_setting_state;
end
end
// Next State Logic
always @(*) begin
case (state)
TIME_DISPLAY: begin
if (mode_pressed) next_state = ALARM;
else next_state = TIME_DISPLAY;
end
ALARM: begin
if (mode_pressed) next_state = STOPWATCH;
else next_state = ALARM;
end
STOPWATCH: begin
if (mode_pressed) next_state = SETTINGS;
else next_state = STOPWATCH;
end
SETTINGS: begin
if (mode_pressed) next_state = TIME_DISPLAY;
else next_state = SETTINGS;
end
default: next_state = TIME_DISPLAY;
endcase
end
// Setting State Logic
always @(*) begin
if (state != SETTINGS) begin
next_setting_state = SET_HOURS;
end else begin
case (setting_state)
SET_HOURS: begin
if (set_pressed) next_setting_state = SET_MINUTES;
else next_setting_state = SET_HOURS;
end
SET_MINUTES: begin
if (set_pressed) next_setting_state = SET_HOURS;
else next_setting_state = SET_MINUTES;
end
default: next_setting_state = SET_HOURS;
endcase
end
end
// Time Keeping Logic
always @(posedge one_hz_clk) begin
if (state == TIME_DISPLAY || state == ALARM) begin
current_minutes <= (current_minutes == 59) ? 0 : current_minutes + 1;
current_hours <= (current_minutes == 59 && current_hours == 23) ? 0 : current_hours + (current_minutes == 59);
end
end
// Alarm Logic
always @(*) begin
alarm_active <= (state == ALARM && alarm_hours == current_hours && alarm_minutes == current_minutes);
end
// Stopwatch Logic
always @(posedge one_hz_clk) begin
if (state == STOPWATCH && stopwatch_running) begin
stopwatch_seconds <= stopwatch_seconds + 1;
end
end
// Settings Adjustment Logic
always @(posedge clk) begin
if (state == SETTINGS) begin
case (setting_state)
SET_HOURS: begin
if (adjust_up_pressed) current_hours <= (current_hours == 23) ? 0 : current_hours + 1;
if (adjust_down_pressed) current_hours <= (current_hours == 0) ? 23 : current_hours - 1;
end
SET_MINUTES: begin
if (adjust_up_pressed) current_minutes <= (current_minutes == 59) ? 0 : current_minutes + 1;
if (adjust_down_pressed) current_minutes <= (current_minutes == 0) ? 59 : current_minutes - 1;
end
endcase
end
end
// Output Assignment
always @(*) begin
hours = current_hours;
minutes = current_minutes;
in_setting_mode = (state == SETTINGS);
stopwatch_running = (state == STOPWATCH && adjust_up_pressed); // Example logic to start/stop stopwatch
end
endmodule
// Structural Approach
// Not implemented
// Testbench for Digital Watch FSM
// Not working, but good enough for learning purposes
`timescale 1ns / 1ps
module digital_watch_fsm_tb;
// Inputs
reg clk;
reg reset;
reg mode_button;
reg set_button;
reg adjust_up;
reg adjust_down;
// Outputs
wire [3:0] hours;
wire [3:0] minutes;
wire alarm_active;
wire stopwatch_running;
wire in_setting_mode;
// Instantiate the Unit Under Test (UUT)
digital_watch_fsm uut (
.clk(clk),
.reset(reset),
.mode_button(mode_button),
.set_button(set_button),
.adjust_up(adjust_up),
.adjust_down(adjust_down),
.hours(hours),
.minutes(minutes),
.alarm_active(alarm_active),
.stopwatch_running(stopwatch_running),
.in_setting_mode(in_setting_mode)
);
// Clock generation
initial begin
clk = 0;
forever #10 clk = ~clk; // Clock with period 20ns
end
// Test sequence
initial begin
// Initialize Inputs
reset = 1;
mode_button = 0;
set_button = 0;
adjust_up = 0;
adjust_down = 0;
// Wait for global reset
#100;
reset = 0;
// Switch to Alarm Mode
#20 mode_button = 1;
#20 mode_button = 0;
// Switch to Stopwatch Mode
#40 mode_button = 1;
#20 mode_button = 0;
// Start Stopwatch
#40 adjust_up = 1;
#20 adjust_up = 0;
// Stop Stopwatch
#100 adjust_up = 1;
#20 adjust_up = 0;
// Switch to Settings Mode
#40 mode_button = 1;
#20 mode_button = 0;
// Adjust Hours
#40 adjust_up = 1;
#20 adjust_up = 0;
// Adjust Minutes
#40 set_button = 1;
#20 set_button = 0;
#40 adjust_up = 1;
#20 adjust_up = 0;
// Return to Time Display
#40 mode_button = 1;
#20 mode_button = 0;
// Complete Test
#100;
$finish;
end
// Monitor the outputs
initial begin
$monitor("Time: %0d:%0d, Alarm Active: %b, Stopwatch Running: %b, In Setting Mode: %b",
hours, minutes, alarm_active, stopwatch_running, in_setting_mode);
end
endmodule
/*
* Project 41: 4-Bit Ripple Carry Adder
*/
// Behavioral Approach
module ripple_carry_adder4bit_behavioral(input wire [3:0] a, input wire [3:0] b, output wire [3:0] sum, output wire carry_out);
assign {carry_out, sum} = a + b;
endmodule
// Structural Approach
module ripple_carry_adder_4bit(
input wire [3:0] a, // 4-bit input a
input wire [3:0] b, // 4-bit input b
input wire carry_in, // Carry input
output wire [3:0] sum, // 4-bit sum output
output wire carry_out // Carry output
);
wire carry0, carry1, carry2; // Intermediate carry wires
// Instantiate the full adders
full_adder_structural FA0 (a[0], b[0], carry_in, sum[0], carry0);
full_adder_structural FA1 (a[1], b[1], carry0, sum[1], carry1);
full_adder_structural FA2 (a[2], b[2], carry1, sum[2], carry2);
full_adder_structural FA3 (a[3], b[3], carry2, sum[3], carry_out);
endmodule
/*
* Project 42: SR (Set-Reset) Latch
*/
// Behavioral Approach
module sr_latch(
input wire S, // Set
input wire R, // Reset
output reg Q, // Output
output reg Qn // Complement of the output
);
always @(S or R) begin
case ({S, R})
2'b01: {Q, Qn} = 2'b10;
2'b10: {Q, Qn} = 2'b01;
2'b00: {Q, Qn} = {Q, Qn}; // Hold state
default: {Q, Qn} = 2'bxx; // Undefined state
endcase
end
endmodule
// Structural Approach
module sr_latch_structural(
input wire S,
input wire R,
output wire Q,
output wire Qn
);
nor (Qn, S, Q);
nor (Q, R, Qn);
endmodule
/*
* Project 43: D (Data) Latch
*/
// Behavioral Approach
module d_latch(
input wire D, // Data input
input wire EN, // Enable
output reg Q // Output
);
always @(EN or D) begin
if (EN) Q = D;
end
endmodule
// Structural Approach
module d_latch_structural(
input wire D,
input wire EN,
output wire Q,
output wire Qn
);
wire nD, nEN, S, R;
not (nD, D);
not (nEN, EN);
and (S, D, EN);
and (R, nD, EN);
nor (Q, R, Qn);
nor (Qn, S, Q);
endmodule
/*
* Project 44: Gated SR Latch
*/
// Behavioral Approach
module gated_sr_latch(
input wire S, // Set
input wire R, // Reset
input wire EN, // Enable
output reg Q, // Output
output reg Qn // Complement of the output
);
always @(EN or S or R) begin
if (EN) begin
case ({S, R})
2'b01: {Q, Qn} = 2'b10;
2'b10: {Q, Qn} = 2'b01;
2'b00: {Q, Qn} = {Q, Qn}; // Hold state
default: {Q, Qn} = 2'bxx; // Undefined state
endcase
end
end
endmodule
// Structural Approach
module gated_sr_latch_structural(
input wire S,
input wire R,
input wire EN,
output wire Q,
output wire Qn
);
wire nS, nR, S_and_EN, R_and_EN;
not (nS, S);
not (nR, R);
and (S_and_EN, S, EN);
and (R_and_EN, R, EN);
nor (Q, R_and_EN, Qn);
nor (Qn, S_and_EN, Q);
endmodule
/*
* Project 45: Gated D Latch
*/
// Behavioral Approach
module gated_d_latch(
input wire D, // Data input
input wire EN, // Enable
output reg Q // Output
);
always @(EN or D) begin
if (EN) Q = D;
// When EN is low, the state is held
end
endmodule
// Structural Approach
module gated_d_latch_structural(
input wire D,
input wire EN,
output wire Q,
output wire Qn
);
wire nD, nEN, S, R;
not (nD, D);
not (nEN, EN);
and (S, D, EN);
and (R, nD, EN);
nor (Q, R, Qn);
nor (Qn, S, Q);
endmodule
/*
* Project 46: T (Toggle) Latch
*/
// Behavioral Approach
module t_latch(
input wire T, // Toggle input
input wire EN, // Enable
output reg Q // Output
);
always @(EN or T) begin
if (EN && T) Q = ~Q;
// When EN is low or T is low, the state is held
end
endmodule
// Structural Approach
module t_latch_structural(
input wire T,
input wire EN,
output wire Q,
output wire Qn
);
wire T_and_EN, nT_and_EN;
and (T_and_EN, T, EN);
not (nT_and_EN, T_and_EN);
nor (Q, nT_and_EN, Qn);
nor (Qn, T_and_EN, Q);
endmodule
/*
* Project 47: D (Data) Flip-Flop
*/
// Behavioral Approach
module d_flip_flop_behavioral(
input wire D,
input wire clk,
output reg Q
);
always @(posedge clk) begin
Q <= D;
end
endmodule
// Structural Approach
module d_flip_flop_structural(
input wire D,
input wire clk,
output wire Q
);
wire nD, nQ, set, reset;
not (nD, D);
nand (set, D, clk);
nand (reset, nD, clk);
nand (Q, set, nQ);
nand (nQ, reset, Q);
endmodule
/*
* Project 48: T (Toggle) Flip-Flop
*/
// Behavioral Approach
module t_flip_flop_behavioral(
input wire T,
input wire clk,
output reg Q
);
always @(posedge clk) begin
if (T) Q <= ~Q;
end
endmodule
// Structural Approach
module t_flip_flop_structural(
input wire T,
input wire clk,
output wire Q
);
wire D;
xor (D, Q, T);
d_flip_flop_structural dff(D, clk, Q);
endmodule
/*
* Project 49: JK Flip-Flop
*/
// Behavioral Approach
module jk_flip_flop_behavioral(
input wire J,
input wire K,
input wire clk,
output reg Q
);
always @(posedge clk) begin
case ({J, K})
2'b00: Q <= Q; // Hold state
2'b01: Q <= 0; // Reset
2'b10: Q <= 1; // Set
2'b11: Q <= ~Q; // Toggle
endcase
end
endmodule
// Structural Approach
module jk_flip_flop_structural(
input wire J,
input wire K,
input wire clk,
output wire Q
);
wire nQ, set, reset, J_and_clk, K_and_clk;
nand (J_and_clk, J, clk);
nand (K_and_clk, K, clk);
nand (set, J_and_clk, nQ);
nand (reset, K_and_clk, Q);
nand (Q, set, reset);
nand (nQ, reset, set);
endmodule
/*
* Project 50: Master-Slave JK Flip-Flop
*/
// Behavioral Approach
module master_slave_d_flip_flop_behavioral(
input wire D,
input wire clk,
output reg Q
);
reg master;
always @(posedge clk) begin
master <= D; // Capture the input at the rising edge
end
always @(negedge clk) begin
Q <= master; // Transfer to output on the falling edge
end
endmodule
// Structural Approach
module master_slave_d_flip_flop_structural(
input wire D,
input wire clk,
output wire Q
);
wire nclk, master;
not (nclk, clk);
// Master latch (transparent when clk is high)
d_latch master_latch (
.D(D),
.EN(clk),
.Q(master)
);
// Slave latch (transparent when clk is low)
d_latch slave_latch (
.D(master),
.EN(nclk),
.Q(Q)
);
endmodule
/*
* Project 51: SR Flip-Flop
*/
// Behavioral Approach
module sr_flip_flop_behavioral(
input wire S,
input wire R,
input wire clk,
output reg Q
);
always @(posedge clk) begin
case ({S, R})
2'b00: Q <= Q; // Hold state
2'b01: Q <= 0; // Reset
2'b10: Q <= 1; // Set
2'b11: ; // Undefined
endcase
end
endmodule
// Structural Approach
module sr_flip_flop_structural(
input wire S,
input wire R,
input wire clk,
output wire Q
);
wire nQ, S_and_clk, R_and_clk;
nand (S_and_clk, S, clk);
nand (R_and_clk, R, clk);
nand (Q, S_and_clk, nQ);
nand (nQ, R_and_clk, Q);
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment