BLESSING BENZER B.S 3122224004002 Ex No: 1 Date: 06/03/2023 EXHAUSTIVE TESTBENCH FOR 1 BIT FULL ADDER AIM: To develop an exhaustive testbench for 1 bit full adder using Verilog HDL SOFTWARE REQUIRED: Xilinx Vivado THEORY: Full Adder is the adder which adds three inputs and produces two outputs. The first two inputs are A and B and the third input is an input carry as C-IN. The output carry is designated as C-OUT and the normal output is designated as S which is SUM. A full adder logic is designed in such a manner that can take eight inputs together to create a byte-wide adder and cascade the carry bit from one adder to another. 1 BLESSING BENZER B.S 3122224004002 VERILOG CODE: module adder(a,b,cin,sum,carry); input a,b,cin; output sum,carry; assign sum = a^b^cin; assign carry = (a*b)|(b*cin)|(a*cin); endmodule TESTBENCH: module adder_tb; reg a,b,cin; wire sum,carry; adder ad(a,b,cin,sum,carry); initial begin $monitor($time,"a=%b,b=%b,cin=%b,sum=%b,carry=%b",a,b,cin,sum,carry); end initial begin a=1'b0;b=1'b0;cin=1'b0; #100 a=1'b0;b=1'b0;cin=1'b1; #100 a=1'b0;b=1'b1;cin=1'b0; #100 a=1'b0;b=1'b1;cin=1'b1; #100 a=1'b1;b=1'b0;cin=1'b0; #100 a=1'b1;b=1'b0;cin=1'b1; #100 a=1'b1;b=1'b1;cin=1'b0; #100 a=1'b1;b=1'b1;cin=1'b1; end endmodule 2 BLESSING BENZER B.S 3122224004002 BOARD IMPLEMENTATION: SIMULATION OUTPUT: RESULT: An exhaustive testbench for 1 bit full adder has been developed and the output has been verified graphically. 3 BLESSING BENZER B.S 3122224004002 Ex No: 2 Date: 13/03/2023 EXHAUSTIVE TESTBENCH FOR 16 TO 1 MULTIPLEXER AIM: To develop an exhaustive testbench for 16 to 1 multiplexer using Verilog HDL SOFTWARE REQUIRED: Xilinx Vivado THEORY: A 16x1 mux can be implemented using 5 4x1 muxes. 4 of these multiplexers can be used as first stage to mux 4 inputs each with two least significant bits of select lines (S0 and S1), resulting in 4 intermediate outputs, which, then can be muxed again using a 4:1 mux. 4 BLESSING BENZER B.S 3122224004002 VERILOG CODE: module mux_4x1(out,in,sel); input [0:3] in; input [0:1] sel; output out; wire a,b,c,d,n1,n2,a1,a2,a3,a4; not n(n1,sel[1]); not nn(n2,sel[0]); and (a1,in[0],n1,n2); and (a2,in[1],n2,sel[1]); and (a3,in[2],sel[0],n1); and (a4,in[3],sel[0],sel[1]); or or1(out,a1,a2,a3,a4); endmodule module mux_16x1(out,in,sel); input [0:15] in; input [0:3] sel; output out; wire [0:3] ma; mux_4x1 mux1(ma[0],in[0:3],sel[2:3]); mux_4x1 mux2(ma[1],in[4:7],sel[2:3]); mux_4x1 mux3(ma[2],in[8:11],sel[2:3]); mux_4x1 mux4(ma[3],in[12:15],sel[2:3]); mux_4x1 mux5(out,ma,sel[0:1]); endmodule TESTBENCH: module mux_tb; reg [0:15] in; reg [0:3] sel; wire out; mux_16x1 mux(out,in,sel); initial begin $monitor("in=%b | sel=%b | out=%b", in,sel,out); end initial begin in=16'b1000000000000000; sel=4'b0000; #30 in=16'b0111111111111111; sel=4'b0000; #30 in=16'b0100000000000000; sel=4'b0001; #30 in=16'b1011111111111111; sel=4'b0001; #30 in=16'b0010000000000000; sel=4'b0010; #30 in=16'b1101111111111111; sel=4'b0010; 5 BLESSING BENZER B.S 3122224004002 #30 in=16'b0001000000000000; #30 in=16'b1110111111111111; #30 in=16'b0000100000000000; #30 in=16'b1111011111111111; #30 in=16'b0000010000000000; #30 in=16'b1111101111111111; #30 in=16'b0000001000000000; #30 in=16'b1111110111111111; #30 in=16'b0000000100000000; #30 in=16'b1111111011111111; #30 in=16'b0000000010000000; #30 in=16'b1111111101111111; #30 in=16'b0000000001000000; #30 in=16'b1111111110111111; #30 in=16'b0000000000100000; #30 in=16'b1111111111011111; #30 in=16'b0000000000010000; #30 in=16'b1111111111101111; #30 in=16'b0000000000001000; #30 in=16'b1111111111110111; #30 in=16'b0000000000000100; #30 in=16'b1111111111111011; #30 in=16'b0000000000000010; #30 in=16'b1111111111111101; #30 in=16'b0000000000000001; #30 in=16'b1111111111111110; end Endmodule sel=4'b0011; sel=4'b0011; sel=4'b0100; sel=4'b0100; sel=4'b0101; sel=4'b0101; sel=4'b0110; sel=4'b0110; sel=4'b0111; sel=4'b0111; sel=4'b1000; sel=4'b1000; sel=4'b1001; sel=4'b1001; sel=4'b1010; sel=4'b1010; sel=4'b1011; sel=4'b1011; sel=4'b1100; sel=4'b1100; sel=4'b1101; sel=4'b1101; sel=4'b1110; sel=4'b1110; sel=4'b1111; sel=4'b1111; 6 BLESSING BENZER B.S 3122224004002 BOARD IMPLEMENTATION: SIMULATION OUTPUT: RESULT: An exhaustive testbench for 16 to 1 multiplexer has been developed and the output has been verified graphically. 7 BLESSING BENZER B.S 3122224004002 Ex No: 3 Date: 20/03/2023 DEVELOPMENT OF LAYERED TESTBENCH FOR FUNCTIONAL VERIFICATION OF A FULL ADDER. AIM: To develop an layered testbench for 1 bit full adder using System Verilog SOFTWARE REQUIRED: Xilinx Vivado THEORY: Full Adder is the adder which adds three inputs and produces two outputs. The first two inputs are A and B and the third input is an input carry as C-IN. The output carry is designated as C-OUT and the normal output is designated as S which is SUM. A full adder logic is designed in such a manner that can take eight inputs together to create a byte-wide adder and cascade the carry bit from one adder to another. 8 BLESSING BENZER B.S 3122224004002 VERILOG CODE: module Adder6( input clk input reset, input [3:0] a , input [3:0] b , input valid, output [6:0] c , ); reg [6:0] tmp_c; //Reset always @(posedge reset) tmp_c <= 0; // Waddition operation always @(posedge clk) if (valid) tmp_c <= a + b; assign c = tmp_c; endmodule ENVIRONMENT: `include "transaction.sv" `include "generator.sv" `include "driver.sv" class environment; //generator and driver instance generator gen; driver driv; //mailbox handle's mailbox gen2driv; //virtual interface virtual intf vif; //constructor function new(virtual intf vif); //get the interface from test this.vif = vif; 9 BLESSING BENZER B.S 3122224004002 //creating the mailbox (Same handle will be shared across generator and driver) gen2driv = new(); //creating generator and driver gen = new(gen2driv); driv = new(vif,gen2driv); endfunction // task pre_test(); driv.reset(); endtask task test(); fork gen.main(); driv.main(); join_any endtask task post_test(); wait(gen.ended.triggered); wait(gen.repeat_count == driv.no_transactions); endtask //run task task run; pre_test(); test(); post_test(); $finish; endtask endclass GENERATOR: class generator; //declaring transaction class rand transaction trans; //repeat count, to specify number of items to generate int repeat_count; 10 BLESSING BENZER B.S 3122224004002 //mailbox, to generate and send the packet to driver mailbox gen2driv; //event, to indicate the end of transaction generation event ended; //constructor function new(mailbox gen2driv); //getting the mailbox handle from env, in order to share the transaction packet between the generator and driver, the same mailbox is shared between both. this.gen2driv = gen2driv; endfunction //main task, generates(create and randomizes) the repeat_count number of transaction packets and puts into mailbox task main(); repeat(repeat_count) begin trans = new(); if( !trans.randomize() ) $fatal("Gen:: trans randomization failed"); trans.display("[ Generator ]"); gen2driv.put(trans); end -> ended; //triggering indicatesthe end of generation endtask endclass DRIVER: class driver; //used to count the number of transactions int no_transactions; //creating virtual interface handle virtual intf vif; //creating mailbox handle mailbox gen2driv; //constructor function new(virtual intf vif,mailbox gen2driv); //getting the interface this.vif = vif; //getting the mailbox handles from environment 11 BLESSING BENZER B.S 3122224004002 this.gen2driv = gen2driv; endfunction //Reset task, Reset the Interface signals to default/initial values task reset; wait(vif.reset); $display("[ DRIVER ] ----- Reset Started -----"); vif.a <= 0; vif.b <= 0; vif.valid <= 0; wait(!vif.reset); $display("[ DRIVER ] ----- Reset Ended -----"); endtask //drivers the transaction items to interface signals task main; forever begin transaction trans; gen2driv.get(trans); @(posedge vif.clk); vif.valid <= 1; vif.a <= trans.a; vif.b <= trans.b; @(posedge vif.clk); vif.valid <= 0; trans.c = vif.c; @(posedge vif.clk); trans.display("[ Driver ]"); no_transactions++; end endtask endclass INTERFACE: interface intf(input logic clk,reset); //declaring logic logic [3:0] logic [3:0] logic [6:0] the signals valid; a; b; c; endinterface 12 BLESSING BENZER B.S 3122224004002 TRANSACTION: class transaction; //declaring the transaction items rand bit [3:0] a; rand bit [3:0] b; bit [6:0] c; function void display(string name); $display("-------------------------"); $display("- %s ",name); $display("-------------------------"); $display("- a = %0d, b = %0d",a,b); $display("- c = %0d",c); $display("-------------------------"); endfunction endclass TESTBENCH: module tbench_top; //clock and reset signal declaration bit clk; bit reset; //clock generation always #5 clk = ~clk; //reset Generation initial begin reset = 1; #5 reset =0; end //creatinng instance of interface, inorder to connect DUT and testcase intf i_intf(clk,reset); //Testcase instance, interface handle is passed to test as an argument test t1(i_intf); //DUT instance, interface signals are connected to the DUT ports Adder6 DUT ( 13 BLESSING BENZER B.S 3122224004002 .clk(i_intf.clk), .reset(i_intf.reset), .a(i_intf.a), .b(i_intf.b), .valid(i_intf.valid), .c(i_intf.c) ); //enabling the wave dump initial begin $dumpfile("dump.vcd"); $dumpvars; end endmodule SIMULATION OUTPUT: RESULT: A layered testbench for 1 bit full adder has been developed and the output has been verified graphically. 14 BLESSING BENZER B.S 3122224004002 Ex. No: 4 DATE: 03/04/2023 FUNCTIONAL VERIFICATION OF 4-BIT ALU USING SYSTEM VERILOG AIM: To design and implement 16-bit ALU in System Verilog using Xilinx Vivado HARDWARE/SOFTWARE REQUIRED: ● Xilinx Vivado 2018.2 THEORY: An Arithmetic Logic Unit (ALU) is a combinational digital electronic circuit that performs arithmetic and bitwise operations on integer binary numbers. This is in contrast to a floating-point unit (FPU), which operates on floating point numbers. An ALU is a fundamental building block of many types of computing circuits, including the central processing unit (CPU) of computers, FPUs, and graphics processing units (GPUs). A single CPU, FPU or GPU may contain multiple ALUs. The inputs to an ALU are the data to be operated on, called operands, and a code indicating the operation to be performed; the ALU's output is the result of the performed operation. In many designs, the ALU also has status inputs or outputs, or both, which convey information about a previous operation or the current operation, respectively, between the ALU and external status registers. BLOCK DIAGRAM: 15 BLESSING BENZER B.S 3122224004002 FUNCTIONAL DESCRIPTION: S3 S2 S1 S0 OPERATION DESCRIPTION 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0 1 0 A+B A-B A*B A/B A&B Addition Subtraction Multiplication Division Bitwise AND 0 0 1 1 0 1 1 0 A|B A^B Bitwise OR Bitwise XOR 0 1 1 1 0 0 1 0 0 1 0 1 ~(A&B) ~(A|B) ~(A^B) Bitwise NAND Bitwise NOR Bitwise XNOR 1 1 1 0 0 1 1 1 0 0 1 0 A<<1 A>>1 B<<1 Shift Left by A Shift Right by A Shift Left by B 1 1 1 1 0 1 1 0 B>>1 A+1 Shift Right by B Increment A by one 1 1 1 1 B+1 Increment B by one DESIGN CODE: module logic_unit( input [7:0] A, B, input [3:0] ALU_Sel, output [7:0] ALU_Out, output CarryOut ); reg [7:0] ALU_Result; wire [8:0] tmp; assign ALU_Out = ALU_Result; assign tmp = {1'b0, A} + {1'b0, B}; assign CarryOut = tmp[8]; always @ (*) begin case (ALU_Sel) 4'b0000: ALU_Result = A + B; 4'b0001: ALU_Result = A - B; 16 BLESSING BENZER B.S 3122224004002 4'b0010: ALU_Result = A * B; 4'b0011: ALU_Result = A / B; 4'b0100: ALU_Result = A << 1; 4'b0101: ALU_Result = A >> 1; 4'b0110: ALU_Result = {A[6:0], A[7]}; 4'b0111: ALU_Result = {A[0], A[7:1]}; 4'b1000: ALU_Result = A & B; 4'b1001: ALU_Result = A | B; 4'b1010: ALU_Result = A ^ B; 4'b1011: ALU_Result = ~(A | B); 4'b1100: ALU_Result = ~(A & B); 4'b1101: ALU_Result = ~(A ^ B); 4'b1110: ALU_Result = (A > B) ? 8'd1 : 8'd0; 4'b1111: ALU_Result = (A == B) ? 8'd1 : 8'd0; default : ALU_Result = A + B; endcase end endmodule TEST BENCH: module alu_testbench(); reg [7:0] A, B; reg [3:0] ALU_Sel; wire [7:0] ALU_Out; wire CarryOut; logic_unit uut ( .A(A), .B(B), .ALU_Sel(ALU_Sel), .ALU_Out(ALU_Out), .CarryOut(CarryOut) ); initial begin $monitor("A=%d, B=%d, ALU_Sel=%d, ALU_Out=%d, CarryOut=%b", A, B, ALU_Sel, ALU_Out, CarryOut); A = 8'hAA; 17 BLESSING BENZER B.S 3122224004002 B = 8'h55; ALU_Sel = 4'b0000; #10; ALU_Sel = 4'b0001; #10; ALU_Sel = 4'b0010; #10; ALU_Sel = 4'b0011; #10; ALU_Sel = 4'b0100; #10; ALU_Sel = 4'b0101; #10; ALU_Sel = 4'b0110; #10; ALU_Sel = 4'b0111; #10; ALU_Sel = 4'b1000; #10; ALU_Sel = 4'b1001; #10; ALU_Sel = 4'b1010; #10; ALU_Sel = 4'b1011; #10; ALU_Sel = 4'b1100; #10; ALU_Sel = 4'b1101; #10; ALU_Sel = 4'b1110; #10; ALU_Sel = 4'b1111; #10; end endmodule SIMULATION OUTPUT: RESULT: Thus the 16-bit ALU using System Verilog code has been designed, implemented, Verified, simulated and synthesized using Xilinx Vivado software. 18 BLESSING BENZER B.S 3122224004002 Ex. No: 5 DATE: 17/04/2023 FUNCTIONAL VERIFICATION OF ASYNCHRONOUS FIFO USING SYSTEM VERILOG AIM: To implement an 8*64 FIFO with read and write ports of the FIFO at the same clock. ● To generate control signals to indicate the FIFO full/empty conditions using System Verilog. HARDWARE/SOFTWARE REQUIRED: ● operating ● Xilinx Vivado 2019.2 THEORY: FIFO is used for synchronization purposes in computer and CPU hardware. FIFO is generally implemented as a circular queue, and thus has a read pointer and a write pointer. A synchronous FIFO uses the same clock for reading and writing. An asynchronous FIFO, however, uses separate clocks for reading and writing. 19 BLESSING BENZER B.S 3122224004002 BLOCK DIAGRAM: DESIGN CODE: module synchronous_fifo #(parameter DEPTH=8, DATA_WIDTH=8) ( input clk, rst_n, input w_en, r_en, input [DATA_WIDTH-1:0] data_in, 20 BLESSING BENZER B.S 3122224004002 output reg [DATA_WIDTH-1:0] data_out, output full, empty); reg [$clog2(DEPTH)-1:0] w_ptr, r_ptr; reg [DATA_WIDTH-1:0] fifo[DEPTH]; // Set Default values on reset. always@(posedge clk) begin if(!rst_n) begin w_ptr <= 0; r_ptr <= 0; data_out <= 0; end end // To write data to FIFO always@(posedge clk) begin if(w_en & !full)begin fifo[w_ptr] <= data_in; w_ptr <= w_ptr + 1; end end // To read data from FIFO always@(posedge clk) begin if(r_en & !empty) begin data_out <= fifo[r_ptr]; r_ptr <= r_ptr + 1; end end assign full = ((w_ptr+1'b1) == r_ptr); assign empty = (w_ptr == r_ptr); endmodule Testbench module synchronous_fifo #(parameter DEPTH=8, DATA_WIDTH=8) ( input clk, rst_n, input w_en, r_en, input [DATA_WIDTH-1:0] data_in, output reg [DATA_WIDTH-1:0] data_out, output full, empty); reg [$clog2(DEPTH)-1:0] w_ptr, r_ptr; 21 BLESSING BENZER B.S 3122224004002 reg [DATA_WIDTH-1:0] fifo[DEPTH]; // Set Default values on reset. always@(posedge clk) begin if(!rst_n) begin w_ptr <= 0; r_ptr <= 0; data_out <= 0; end end // To write data to FIFO always@(posedge clk) begin if(w_en & !full)begin fifo[w_ptr] <= data_in; w_ptr <= w_ptr + 1; end end // To read data from FIFO always@(posedge clk) begin if(r_en & !empty) begin data_out <= fifo[r_ptr]; r_ptr <= r_ptr + 1; end end assign full = ((w_ptr+1'b1) == r_ptr); assign empty = (w_ptr == r_ptr); endmodule SIMULATION OUTPUT 22 BLESSING BENZER B.S 3122224004002 RESULT: Thus the 16-bit ALU using System Verilog code has been designed, implemented, Verified, simulated and synthesized using Xilinx Vivado software. 23 BLESSING BENZER B.S 3122224004002 Ex No: 6 DATE: 01/05/2023 FUNCTIONAL VERIFICATION OF ROUND ROBIN ARBITER USING SYSTEM VERILOG AIM: To implement a Round Robin Arbiter in SystemVerilog using Xilinx Vivado. THEORY: A round-robin arbiter is a type of scheduling algorithm used in computer systems to determine the order in which multiple devices or processes are granted access to a shared resource. It follows a simple and fair approach by cycling through the devices or processes in a circular manner, ensuring that each participant receives an equal opportunity for resource access. In the case of an arbiter, it can be used to control access to a shared bus or channel within a computer system. The round-robin arbiter assigns time slots or priorities to different devices or processes in a rotating fashion. Each participant gets a turn to access the shared resource for a fixed duration or until its task is completed, after which the arbiter moves on to the next participant in the sequence. This method ensures that no participant is favored over others, providing fairness and preventing starvation of any individual device or process. Round-robin arbitration is widely used in various systems, including networking, operating systems, and hardware designs, to distribute resource access fairly among multiple entities. BLOCK DIAGRAM: 24 BLESSING BENZER B.S 3122224004002 The case statement used for Round Robin arbitration is as follows: case (rotate_ptr[1:0]) 2'b00: shift_request[3:0] = request[3:0]; 2'b01: shift_request[3:0] = {request[0],request[3:1]}; 2'b10: shift_request[3:0] = {request[1:0],request[3:2]}; 2'b11: shift_request[3:0] = {request[2:0],request[3]}; endcase DESIGN CODE: module round_robin_arbiter_fixed_time_slices( input clk, input rst_n, input [3:0] REQ, output reg [3:0] GNT); reg [2:0] present_state; reg [2:0] next_state; parameter [2:0] S_ideal = 3'b000; parameter [2:0] S_0 = 3'b001; parameter [2:0] S_1 = 3'b010; parameter [2:0] S_2 = 3'b011; parameter [2:0] S_3 = 3'b100; always @ (posedge clk or negedge rst_n) // State Register , Sequential always block begin if(!rst_n) present_state <= S_ideal; else present_state <= next_state; end always @(*) // Next State , Combinational always block begin case(present_state) S_ideal : begin if(REQ[0]) begin next_state = S_0; end else if(REQ[1]) begin next_state = S_1; 25 BLESSING BENZER B.S 3122224004002 end else if(REQ[2]) begin next_state = S_2; end else if(REQ[3]) begin next_state = S_3; end else begin next_state = S_ideal; end end // S_ideal S_0 : begin if(REQ[1]) begin next_state = S_1; end else if(REQ[2]) begin next_state = S_2; end else if(REQ[3]) begin next_state = S_3; end else if(REQ[0]) begin next_state = S_0; end else begin next_state = S_ideal; end end // S_0 S_1 : begin if(REQ[2]) begin next_state = S_2; end else if(REQ[3]) begin next_state = S_3; end else if(REQ[0]) begin next_state = S_0; 26 BLESSING BENZER B.S 3122224004002 end else if(REQ[1]) begin next_state = S_1; end else begin next_state = S_ideal; end end //S_1 S_2 : begin if(REQ[3]) begin next_state = S_3; end else if(REQ[0]) begin next_state = S_0; end else if(REQ[1]) begin next_state = S_1; end else if(REQ[2]) begin next_state = S_2; end else begin next_state = S_ideal; end end // S_2 S_3 : begin if(REQ[0]) begin next_state = S_0; end else if(REQ[1]) begin next_state = S_1; end else if(REQ[2]) begin next_state = S_2; end else if(REQ[3]) begin next_state = S_3; end 27 BLESSING BENZER B.S 3122224004002 else begin next_state = S_ideal; end end // S_3 default : begin if(REQ[0]) begin next_state = S_0; end else if(REQ[1]) begin next_state = S_1; end else if(REQ[2]) begin next_state = S_2; end else if(REQ[3]) begin next_state = S_3; end else begin next_state = S_ideal; end end // default endcase // case(state) end always @(*) // Output , Combinational always block begin case(present_state) S_0 : begin GNT = 4'b0001; end S_1 : begin GNT = 4'b0010; end S_2 : begin GNT = 4'b0100; end S_3 : begin GNT = 4'b1000; end default : begin GNT = 4'b0000; end endcase end endmodule // Round Robin Arbiter with Fixed Time Slice 28 BLESSING BENZER B.S 3122224004002 TESTBENCH: module fixed_priority_Arbiter_fixed_time_slices_test; reg clk; reg rst_n; reg [3:0] REQ; wire [3:0] GNT; //Instantiate Design Under Test round_robin_arbiter_fixed_time_slices DUT(.clk(clk), .rst_n(rst_n), .REQ(REQ), .GNT(GNT)); //Generate a 10 ns Time Period Clock always #5 clk = ~clk; //Drive the DUT or Generate stimuli for the DUT initial begin clk = 0; rst_n = 1; REQ = 4'b0; // Assert the Asynchronous Reset after 1 clock period #10 rst_n = 0; //Deassert the Reset #5 rst_n = 1; @(negedge @(negedge @(negedge @(negedge @(negedge @(negedge @(negedge @(negedge clk) clk) clk) clk) clk) clk) clk) clk) REQ REQ REQ REQ REQ REQ REQ REQ = = = = = = = = 4'b1000; 4'b1010; 4'b0010; 4'b0110; 4'b1110; 4'b1111; 4'b0100; 4'b0010; #5 rst_n = 0; #100 $finish; end initial begin // below two lines are used to show waveform $dumpfile("dump.vcd"); $dumpvars(1); end endmodule 29 BLESSING BENZER B.S 3122224004002 SIMULATION OUTPUT: RESULT: Thus the Round Robin Arbiter using System Verilog code has been designed, implemented, Verified, simulated and synthesized using Xilinx Vivado software. 30 BLESSING BENZER B.S 3122224004002 Ex No: 7 DATE: 22/05/2023 FUNCTIONAL VERIFICATION OF SHIFT REGISTER USING SYSTEM VERILOG AIM: To implement a Round Robin Arbiter in SystemVerilog using Xilinx Vivado. THEORY: A Register is a device that is used to store such information. It is a group of flip-flops connected in series used to store multiple bits of data. The information stored within these registers can be transferred with the help of shift registers. Shift Register is a group of flip flops used to store multiple bits of data. The bits stored in such registers can be made to move within the registers and in/out of the registers by applying clock pulses. An n-bit shift register can be formed by connecting n flip-flops where each flip-flop stores a single bit of data. The registers which will shift the bits to the left are called “Shift left registers”. The registers which will shift the bits to the right are called “Shift right registers”. BLOCK DIAGRAM: 31 BLESSING BENZER B.S 3122224004002 DESIGN CODE: module shiftregister ( input wire clk, input wire reset, input wire d_in, output wire [2:0] q_out); wire q1, q2, q3; DFlipFlop dff1 ( .clk(clk), .reset(reset), .d(d_in), .q(q1) ); DFlipFlop dff2 ( .clk(clk), .reset(reset), .d(q1), .q(q2)); DFlipFlop dff3 ( .clk(clk), .reset(reset), .d(q2), .q(q3)); assign q_out = {q3, q2, q1}; endmodule TEST BENCH: module shifttb; reg clk; reg reset; reg d_in; wire [2:0] q_out; 32 BLESSING BENZER B.S 3122224004002 shiftregister dut ( .clk(clk), .reset(reset), .d_in(d_in), .q_out(q_out)); initial begin clk = 0; reset = 1; d_in = 0; #10 reset = 0; // Deassert reset after 10 time units // Test 1: Shift in a sequence of 1's #20 d_in = 1; #10 d_in = 1; #10 d_in = 1; #10 d_in = 0; // Expected output: 110 // Shifted by 1: 011 // Shifted by 1 again: 110 // Shifted by 1 again: 101 // The output should stabilize after 50 time units #50 $finish; end always begin #5 clk = ~clk; end endmodule SIMULATION OUTPUT: 33 BLESSING BENZER B.S 3122224004002 RESULT: Thus the Shift register using System Verilog code has been designed, implemented, Verified, simulated and synthesized using Xilinx Vivado software. 34 BLESSING BENZER B.S 3122224004002 Ex. No: 8 DATE: 05/06/2023 AUTOMATIC TEST PATTERN GENERATION FOR FULL ADDER AIM: To design and implement Automatic Test pattern generation for Pseudo Random Generator Xilinx Vivado HARDWARE/SOFTWARE REQUIRED: ● Xilinx Vivado 2018.2 THEORY: Automatic Test Pattern Generation (ATPG) is a process in which test patterns are generated automatically to test and verify the functionality of digital circuits or systems. The goal is to achieve high fault coverage, detecting and diagnosing faults or errors within the design. . Pseudo-random pattern generators (PRPGs) are commonly used in ATPG algorithms. To generate test patterns for a pseudo-random generator (PRG) during ATPG, you can follow these general steps: Characterize the PRG: Understand the structure and behavior of the PRG, including its input and output specifications, internal states, and feedback mechanism. Define the test objectives: Determine the specific faults or behaviors you want to detect in the PRG, such as stuck-at faults or sequential faults. Select an ATPG algorithm: Choose an ATPG algorithm that is suitable for test objectives and the characteristics of the PRG. Generate the fault list: Create a list of potential faults or error conditions that could occur in the PRG based on your test objectives. Apply the ATPG algorithm: Use the selected ATPG algorithm to automatically generate test patterns that can detect the faults identified in the fault list. Simulate the test patterns: Apply the generated test patterns to the PRG and simulate its behavior. This involves capturing the output responses of the PRG and comparing them against the expected responses based on the fault model. 35 BLESSING BENZER B.S 3122224004002 Evaluate the test coverage: Analyze the effectiveness of the generated test patterns by measuring the fault coverage achieved. This helps determine the quality of the generated test patterns and whether further refinement is necessary. BLOCK DIAGRAM: DESIGN CODE: module PseudoRandomGenerator_3bit( input wire clk, input wire rst, output reg [2:0] rand_num ); reg [2:0] seed; always @(posedge clk or posedge rst) begin if (rst) begin seed <= 3'b111; // Initial seed value rand_num <= 0; end else begin seed <= {seed[1:0], seed[2] ^ seed[1]}; rand_num <= seed; end end endmodule 36 BLESSING BENZER B.S 3122224004002 TEST BENCH: module Testbench(); reg clk; reg rst; wire [2:0] rand_num; PseudoRandomGenerator_3bit prng ( .clk(clk), .rst(rst), .rand_num(rand_num) ); initial begin clk = 0; rst = 1; #10 rst = 0; #1000 $finish; end always #5 clk = ~clk; endmodule SIMULATION OUTPUT: RESULT: Automatic Test Pattern Generation for Adder using System Verilog code has been designed, implemented, Verified, simulated using Xilinx Vivado software. 37 BLESSING BENZER B.S 3122224004002 Ex. No: 9 DATE:12/06/2023 AUTOMATIC TEST PATTERN GENERATION FOR COUNTER AIM: To design and implement Automatic Test pattern generation for Pseudo Random Generator Xilinx Vivado HARDWARE/SOFTWARE REQUIRED: ● Xilinx Vivado 2018.2 THEORY: Automatic Test Pattern Generation (ATPG) is a process in which test patterns are generated automatically to test and verify the functionality of digital circuits or systems. The goal is to achieve high fault coverage, detecting and diagnosing faults or errors within the design. . Pseudo-random pattern generators (PRPGs) are commonly used in ATPG algorithms. To generate test patterns for a pseudo-random generator (PRG) during ATPG, you can follow these general steps: Characterize the PRG: Understand the structure and behavior of the PRG, including its input and output specifications, internal states, and feedback mechanism. Define the test objectives: Determine the specific faults or behaviors you want to detect in the PRG, such as stuck-at faults or sequential faults. Select an ATPG algorithm: Choose an ATPG algorithm that is suitable for test objectives and the characteristics of the PRG. Generate the fault list: Create a list of potential faults or error conditions that could occur in the PRG based on your test objectives. Apply the ATPG algorithm: Use the selected ATPG algorithm to automatically generate test patterns that can detect the faults identified in the fault list. Simulate the test patterns: Apply the generated test patterns to the PRG and simulate its behavior. This involves capturing the output responses of the PRG and comparing them against the expected responses based on the fault model. 38 BLESSING BENZER B.S 3122224004002 Evaluate the test coverage: Analyze the effectiveness of the generated test patterns by measuring the fault coverage achieved. This helps determine the quality of the generated test patterns and whether further refinement is necessary. BLOCK DIAGRAM: DESIGN CODE: module counter( input wire clk, input wire rst, input wire dir, input wire set1, input wire set2, output reg rand_num ); reg seed; always @(posedge clk) begin if (rst) begin seed <= 1'b0; // Initial seed value rand_num <= 0; end else begin seed <= ~ seed; rand_num <= seed; end end 39 BLESSING BENZER B.S 3122224004002 endmodule TEST BENCH: module countertb(); reg clk; reg rst; reg dir; reg set1; reg set2; wire rand_num; counter prng ( .clk(clk), .rst(rst),.dir(dir),.set1(set1),.set2(set2), .rand_num(rand_num) ); initial begin clk = 0; rst = 1; set1=0; set2=0; #10 dir=0; #10 rst = 0; #10 set1= 1; #10 set1= 0; #55 dir =1; #10 set2= 1; #10 set2= 0; #100 $finish; end always #5 clk = ~clk; endmodule SIMULATION OUTPUT: 40 BLESSING BENZER B.S 3122224004002 RESULT: Automatic Test Pattern Generation for a 4 bit counter using System Verilog code has been designed, implemented, Verified, simulated using Xilinx Vivado software. 41