Last active
January 7, 2024 19:19
-
-
Save mertalp-ulus/2a3141768dec3d224866f3875beabb9c to your computer and use it in GitHub Desktop.
51 Verilog examples for learning purposes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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