LAB – 1: Verilog Abstraction Levels Questions: 1. Write a verilog code for a half adder using data flow abstraction and verify using testbench. 2. Write a verilog for a 1-bit full adder using 2 half adder and 1 or gate and verify using testbench. 3. Write a verilog code for a full adder using data flow abstraction and verify using testbench. 4. Write an RTL and testbench for 2:4 decoder using data flow abstraction. 5. Write an RTL and testbench for a 4:1 MUX using 2:1 MUX. 6. Write an RTL for a bidirectional buffer and verify the same using testbench. 7. Write an RTL and testbench and testbench for a 4-bit Ripple carry adder using 1-bit full adder. 8. Write an RTL for 4X1 mux using decoder and tri state buffer and verify the same using testbench. 9. write 8:3 priority encoder using structural model. Solutions: 1. Write a verilog code for a half adder using data flow abstraction and verify using testbench. RTL Code: module half adder (input a,b, output sum, carry); assign sum = a ^ b; assign carry = a & b; endmodule Testbench: module half_adder_tb(); reg a,b; wire sum, carry; integer i; half_adder DUT(a,b,sum,carry); initial begin a = 1'b0; b = 1'b0; end initial begin for(i=0;i<4;i=i+1) begin {a,b}=i; #10; end end initial #100 $finish; endmodule Waveform: Synthesis circuit: 2. Write a verilog for a 1-bit full adder using 2 half adder and 1 or gate and verify using testbench. RTL Code: module full_adder(a_in, b_in, c_in, sum_out, carry_out); input a_in,b_in,c_in; output sum_out, carry_out; wire w1,w2,w3; half_adder ha1(.a(a_in), .b(b_in),.sum(w1), .carry(w2)); half_adder ha2(.a(w1), .b(c_in),.sum(sum_out), .carry(w3)); or or1(carry_out, w2,w3); endmodule Testbench: module full_adder_tb(); reg a,b,cin; wire sum,carry; integer i; full_adder DUT(a,b,cin,sum,carry); initial begin a = 1'b0; b = 1'b0; cin = 1'b0; end initial begin for (i=0;i<8;i=i+1) begin {a,b,cin}=i; #10; end end initial $monitor("Input a=%b, b=%b, c=%b, Output sum =%b, carry=%b",a,b,cin,sum,carry); initial #100 $finish; endmodule Waveform: Synthesis circuit: 3. Write a verilog code for a full adder using data flow abstraction and verify using testbench. RTL Code: module fulladder_df(a,b,cin,sum,cout); input a,b,cin; output sum,cout; assign sum=a^b^cin; assign cout=(a&b)|(b&cin)|(a&cin); endmodule Testbench: module fulladder_df_tb(); reg a,b,cin; wire sum,cout; integer i; fulladder_df DUT(a,b,cin,sum,cout); initial begin a=1'b0; b=1'b0; cin=1'b0; end initial begin for(i=0;i<8;i=i+1) begin {a,b,cin}=i; #10; end end initial $monitor ("input a=%b, b=%b, cin=%b, sum=%b, cout=%b", a,b,cin,sum,cout); initial #100 $finish; endmodule Waveform: Synthesis circuit: 4. Write an RTL and testbench for 2:4 decoder using data flow abstraction. RTL Code: module decoder2x4(a,b,en,d0,d1,d2,d3); input a,b,en; output d0,d1,d2,d3; assign d0= ~a & ~b & en; assign d1= ~a & b & en; assign d2= a & ~b & en; assign d3= a & b & en; endmodule Testbench: module decoder2x4_tb(); reg a,b,en; wire d0,d1,d2,d3; integer i; decoder2x4 DUT(a,b,en,d0,d1,d2,d3); initial begin a=1'b0; b=1'b0; en=1'b1; end initial begin for(i=0;i<4;i=i+1) begin {a,b}=i; #10; end end initial #100 $finish; endmodule Waveform: Synthesis circuit: 5. Write an RTL and testbench for a 4:1 MUX using 2:1 MUX. RTL Code: module mux4x1(S0,S1,I0,I1,I2,I3,out); input S0,S1,I0,I1,I2,I3; output out; wire w1,w2; mux2x1 m1(.s(S0), .i0(I0), .i1(I1), .y(w1)); mux2x1 m2(.s(S0), .i0(I2), .i1(I3), .y(w2)); mux2x1 m3(.s(S1), .i0(w1), .i1(w2), .y(out)); endmodule module mux2x1(s,i0,i1,y); input s,i0,i1; output y; assign y= (~s&i0)|(s&i1); endmodule Testbench: module mux4x1_tb(); reg S0,S1,I0,I1,I2,I3; wire out; integer i; mux4x1 DUT(S0,S1,I0,I1,I2,I3,out); initial begin S0=1'b0; S1=1'b0; I0=1'b0; I1=1'b0; I2=1'b0; I3=1'b0; end initial begin for(i=0;i<64;i=i+1) begin {S1,S0,I0,I1,I2,I3}=i; #10; end end initial #300 $finish; endmodule Waveform: Synthesis circuit: 6. Write an RTL for a bidirectional buffer and verify the same using testbench. RTL Code: module bi_buff(a,b,ctrl); inout a,b; input ctrl; bufif1 b1(b,a,ctrl); bufif0 b2(a,b,ctrl); endmodule Testbench: module bi_buff_tb(); wire a,b; reg ctrl; reg tempa,tempb; integer i; bi_buff dut(a,b,ctrl); assign a=ctrl?tempa:1'bz; assign b=~ctrl?tempb:1'bz; initial begin for(i=0;i<8;i=i+1) begin {tempa,tempb,ctrl}=i; #10; end end initial $monitor("a=%b,b=%b,ctrl=%b",a,b,ctrl); endmodule Waveform: Synthesis circuit: 7. Write an RTL and testbench and testbench for a 4-bit Ripple carry adder using 1-bit adder. RTL Code: module ripple_carry_adder(a,b,cin,s,carry); output [3:0]s; output carry; input [3:0] a,b; input cin; wire c1,c2,c3; full_adder f1(a[0],b[0],cin,s[0],c1); full_adder f2(a[1],b[1],c1,s[1],c2); full_adder f3(a[2],b[2],c2,s[2],c3); full_adder f4(a[3],b[3],c3,s[3],carry); endmodule Testbench: module ripple_carry_adder_tb(); wire [3:0]s; wire carry; reg [3:0]a,b; reg cin; integer i; ripple_carry_adder DUT(.a(a),.b(b),.cin(cin),.s(s),.carry(carry)); initial begin a=4'b0; b=4'b0; cin=1'b0; end initial begin for(i=0;i<256;i=i+1) begin {a,b}=i; #10; end full end initial $monitor ("input a=%b, b=%b, cin=%b, sum=%b, cout=%b", a,b,cin,s,carry); initial #800 $finish; endmodule Waveform: Synthesis circuit: 8. Write an RTL for 4X1 mux using decoder and tri state buffer and verify the same using testbench. RTL Code: module mux_buf(in,s,y); input [3:0]in; input [1:0]s; output wor y; wire [3:0]w; wire [3:0]x; decoder d1(s,w); bufif1 b1(x[0],in[0],w[0]); bufif1 b2(x[1],in[1],w[1]); bufif1 b3(x[2],in[2],w[2]); bufif1 b4(x[3],in[3],w[3]); assign y=x[0]; assign y=x[1]; assign y=x[2]; assign y=x[3]; endmodule Testbench: module mux_buf_tb(); reg [3:0]in; reg [1:0]s; wire y; integer i; mux_buf dut(in,s,y); initial begin for(i=0;i<64;i=i+1) begin {s,in}=i; #10; end end initial #800 $finish; endmodule Waveform: Synthesis circuit: 9. Write 8:3 priority encoder using structural model. RTL Code: module pr_encoder(in,idle,y); input [7:0]in; output[2:0]y; output idle; wire [7:0]h; pr_circuit c1(in,h,idle); encoder c2(h,y); endmodule module pr_circuit(i,h,idle); input [7:0]i; output [7:0]h; output idle; assign h[7]=i[7]; assign h[6]=i[6]&~i[7]; assign h[5]=i[5]&~i[6]&~i[7]; assign h[4]=i[4]&~i[5]&~i[6]&~i[7]; assign h[3]=i[3]&~i[4]&~i[5]&~i[6]&~i[7]; assign h[2]=i[2]&~i[3]&~i[4]&~i[5]&~i[6]&~i[7]; assign h[1]=i[1]&~i[2]&~i[3]&~i[4]&~i[5]&~i[6]&~i[7]; assign h[0]=i[0]&~i[1]&~i[2]&~i[3]&~i[4]&~i[5]&~i[6]&~i[7]; assign idle=~i[0]&~i[1]&~i[2]&~i[3]&~i[4]&~i[5]&~i[6]&~i[7]; endmodule module encoder(in,y); input [7:0]in; output [2:0]y; assign y[2]=in[4]+in[5]+in[6]+in[7]; assign y[1]=in[2]+in[3]+in[6]+in[7]; assign y[0]=in[1]+in[3]+in[5]+in[7]; endmodule Testbench: module pr_encoder_tb(); reg [7:0]in; wire [2:0]y; wire idle; integer i,chanel_1; pr_encoder dut(in,idle,y); initial begin chanel_1=$fopen("fileoutpr1"); $fmonitor(chanel_1,$time,"input=%b,y=%b",in,y); end initial begin in=8'd0; end initial begin for(i=0;i<256;i=i+1) begin in=i; #10; end end initial $monitor("input=%b,y=%b",in,y); initial #3000 $finish; endmodule Waveform: Synthesis circuit: LAB – 2: Verilog Operators Questions: 1. Work on Operators 2. Write an RTL and Testbench for ALU using arithmetic and logical operators. Solutions: 1. Work on Operators RTL Code: module rand(a,b,y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15,y16,y17,y18,y19,y20,y21,y22,y23,y 24,y25,y26,y27,y28,y29,y30); input [3:0] a,b; output reg [3:0] y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15,y16,y17,y18,y19,y20,y21,y22,y23,y24,y25,y 26,y27,y28,y29,y30; assign a=4'b1010; assign b=4'b1101; always@(*) begin y0=a&&b; y1=a||b; y2=!a; y3=a&b; y4=a|b; y5=~a; y6=a^b; y7=a~^b; y8=&a; y9=|a; y10=~&a; y11=~|a; y12=^a; y13=~^a; y14=a<<b; y15=a>>b; y16=a>>>b; y17=a<<<b; y18=a>b; y19=(a>=b); y20=(a<b); y21=(a<=b); y22=(a==b); y23=(a!=b); y24=(a===b); y25=(a!==b); y26=a+b; y27=a-b; y28=a*b; y29=a/b; y30=a%b; end endmodule Table: Operators Operation Input 1 (a) Input 2 (b) and (&&) Logical Bitwise or (||) 3 0 Out Reason 0 Perform logical operation on the logical value of operands and tells whether it is true or false 1 not (! a) 0 and (&) 1000 or (|) 1111 negation (~) 1010 1101 0101 xor (^) 0111 xnor (~ ^) 1000 and (&) 0 or (|) 1 nand (~ &) Reduction 1 1010 - nor (~ |) 0 xor (^) 0 Xnor (~ ^) 1 shift left (<<) 10000 shift right (>>) 00101 Logical shift shift left (<<<) 10100 - 10000 Arithmetic shift Relational operator shift right (>>>) 11101 a> b 1 a>=b 1 4 3 a<b 0 a<=b 0 a= =b X a!=b Equality operator Arithmetic operators X 1x0z 1x0z a= = =b 1 a! = =b 0 addition (+) 0101 subtraction (-) 0001 multiplication (*) 0011 0010 0110 division (/) 0001 modulus (%) 0001 Perform the operation with the corresponding bits in the operands Performs bit by bit logical operation on the vector operand Vacant positions filled with zeros Vacant position filled with sign bit in case of right shift Test the relation between operands and return a 1 or 0 Test whether the operands are the same or not Perform the corresponding operation on the operands Waveform: Synthesis circuit: 2. Write an RTL and Testbench for ALU using arithmetic and logical operators. RTL Code: module alu(input [7:0]a,b, input [3:0]command_in, input oe, output [15:0]d_out); parameter ADD = 4'b0000, // Add two 8 bit numbers a and b. INC = 4'b0001, // Increment a by 1. SUB = 4'b0010, // Subtracts b from a. DEC = 4'b0011, // Decrement a by 1. MUL = 4'b0100, // Multiply 4 bit numbers a and b. DIV = 4'b0101, // Divide a by b. SHL = 4'b0110, // Shift a to left side by 1 bit. SHR = 4'b0111, // Shift a to right by 1 bit. AND = 4'b1000, // Logical AND operation OR = 4'b1001, // Logical OR operation INV = 4'b1010, // Logical Negation NAND = 4'b1011, // Bitwise NAND NOR = 4'b1100, // Bitwise NOR XOR = 4'b1101, // Bitwise XOR XNOR = 4'b1110, // Bitwise XNOR BUF = 4'b1111; // BUF reg [15:0]out; always@(command_in) begin case(command_in) ADD: out=a+b; INC: out=a+1; SUB: out=a-b; DEC: out=a-1; MUL: out=a*b; DIV: out=a/b; SHL: out=a<<b; SHR: out=a>>b; AND: out=a&b; OR: out=a|b; INV: out=~a; NAND:out=~(a&b); NOR:out=~(a|b); XOR:out=a^b; XNOR:out=~(a^b); BUF:out=a; default: out=16'h0000; endcase end assign d_out = (oe) ? out : 16'hzzzz; endmodule Testbench module alu_tb(); reg [7:0]a,b; reg [3:0]command; reg enable; wire [15:0]out; integer m,n,o; parameter ADD = 4'b0000, // Add two 8 bit numbers a and b. INC = 4'b0001, // Increment a by 1. SUB = 4'b0010, // Subtracts b from a. DEC = 4'b0011, // Decrement a by 1. MUL = 4'b0100, // Multiply 4 bit numbers a and b. DIV = 4'b0101, // Divide a by b. SHL = 4'b0110, // Shift a to left side by 1 bit. SHR = 4'b0111, // Shift a to right by 1 bit. AND = 4'b1000, // Logical AND operation OR = 4'b1001, // Logical OR operation INV = 4'b1010, // Logical Negation NAND = 4'b1011, // Bitwise NAND NOR = 4'b1100, // Bitwise NOR XOR = 4'b1101, // Bitwise XOR XNOR = 4'b1110, // Bitwise XNOR BUF = 4'b1111; // BUF reg [4*8:0]string_cmd; alu dut(a,b,command,enable,out); task initialize; begin {a,b}=16'h0000; end endtask task en_oe(input i); begin enable=i; end endtask task inputs(input [7:0]j,k); begin a=j; b=k; end endtask task cmd (input [3:0]l); begin command=l; end endtask task delay(); begin #10; end endtask always@(command) begin case (command) ADD : string_cmd = "ADD"; INC : string_cmd = "INC"; SUB : string_cmd = "SUB"; DEC : string_cmd = "DEC"; MUL : string_cmd = "MUL"; DIV : string_cmd = "DIV"; SHL : string_cmd = "SHL"; SHR : string_cmd = "SHR"; INV : string_cmd = "INV"; AND : string_cmd = "AND"; OR : string_cmd = "OR"; NAND : string_cmd = "NAND"; NOR : string_cmd = "NOR"; XOR : string_cmd = "XOR"; XNOR : string_cmd = "XNOR"; BUF : string_cmd = "BUF"; endcase end initial begin initialize; en_oe(1'b1); for(m=0;m<16;m=m+1) begin for(n=0;n<16;n=n+1) begin inputs(m,n); for(o=0;o<16;o=o+1) begin command=o; delay; end end end en_oe(0); inputs(8'd20,8'd10); cmd(ADD); delay; en_oe(1); inputs(8'd25,8'd17); cmd(ADD); delay; $finish; end initial $monitor("Input oe=%b, a=%b, b=%b, command=%s, Output out=%b",enable,a,b,string_cmd,out); Endmodule Waveform: Synthesis circuit: LAB – 3: Combinational Logic Questions: 1.Write behavioral description and test bench for 4:1 MUX. 2.Write a behavioral description for a 3:8 decoder and verify using test bench. 3.Write an behavioral description and testbench 8:3 priority encoder. Solutions: 1.Write behavioral description and test bench for 4:1 MUX. RTL Code: module mux41(in,s,y); input [3:0]in; input [1:0]s; output reg y; always@(in,s) begin case(s) 2'b00:y=in[0]; 2'b01:y=in[1]; 2'b10:y=in[2]; 2'b11:y=in[3]; endcase end endmodule Testbench: module mux41_tb(); reg [3:0]in; reg [1:0]s; wire y; integer m,n; mux41 dut(in,s,y); task initialize; begin {in,s}=0; end endtask task inputs(input [3:0]i); begin in=i; end endtask task select(input [1:0]j); begin s=j; end endtask initial begin initialize; for(m=0;m<4;m=m+1) begin select(m); for(n=0;n<16;n=n+1) begin inputs(n); #10; end end end endmodule Waveform: Synthesis circuit: 2.Write a behavioral description for a 3:8 decoder and verify using test bench. RTL Code: module decoder38(in,en,d); input [2:0]in; input en; output reg [7:0]d; always@(*) begin if(en==1) begin case(in) 3'b000:d=8'b0000_0000; 3'b001:d=8'b0000_0010; 3'b010:d=8'b0000_0100; 3'b011:d=8'b0000_1000; 3'b100:d=8'b0001_0000; 3'b101:d=8'b0010_0000; 3'b110:d=8'b0100_0000; 3'b111:d=8'b1000_0000; default: d=8'h00; endcase end else d=8'h00; end endmodule Testbench: module decoder38_tb(); reg [2:0]in; reg en; wire [7:0]d; integer m; decoder38 dut(in,en,d); task initialize; begin {in,en}=0; end endtask task inputs(input [2:0]i); begin in=i; end endtask initial begin initialize; for(m=0;m<8;m=m+1) begin en=1'b1; inputs(m); #10; end end endmodule Waveform: Synthesis circuit: 3.Write a behavioral description and testbench 8:3 priority encoder. RTL Code: module pr_encoder(in,y,idle); input [7:0] in; output reg [2:0] y; output reg idle; always@(in) begin if(in[7]==1'b1) begin y=3'b111; idle=1'b0; end else if(in[6]==1'b1) begin y=3'b110; idle=1'b0; end else if(in[5]==1'b1) begin y=3'b101; idle=1'b0; end else if(in[4]==1'b1) begin y=3'b100; idle=1'b0; end else if(in[3]==1'b1) begin y=3'b011; idle=1'b0; end else if(in[2]==1'b1) begin y=3'b010; idle=1'b0; end else if(in[1]==1'b1) begin y=3'b001; idle=1'b0; end else if(in[0]==1'b1) begin y=3'b000; idle=1'b0; end else begin y=3'bzzz; idle=1'b1; end end endmodule Testbench: module pr_encoder_tb(); reg [7:0] in; wire [2:0] y; wire idle; integer m; pr_encoder dut(in,y,idle); task initialize; begin in=0; end endtask task inputs(input[7:0]i); begin in=i; end endtask initial begin initialize; for(m=0;m<256;m=m+1) begin inputs(m); #10; end end endmodule Waveform: Synthesis circuit: