Chapter 4 Expressions 1 Verilog HDL:Digital Design and Modeling Chapter 4 Expressions
Chapter 4 Expressions 2 Page 120 //example of using a parameter module param1 (a, b, cin, sum); parameter width = 8; input [width-1:0] a, b; //a and b are 8 bits (7:0) input cin; //cin is a scalar output [width:0] sum; //sum is 9 bits (8:0) //to include cout //inputs default to wire reg [width:0] sum; always @ (a or b or cin) sum = a + b + cin; Figure 4.2 Module for the 8-bit adder of Figure 4.1 illustrating the use of the parameter statement. //param1 test bench module param1_tb; parameter width = 8; reg [width-1:0] a, b; reg cin; wire [width:0] sum; //display variables $monitor ("a b cin = %b_%b_%b, sum = %b", a, b, cin, sum); //continued on next page Figure 4.3 Test bench for the module of Figure 4.2.
Chapter 4 Expressions 3 //apply input vectors #0 a = 8'b0000_0011; b = 8'b0000_0100; cin = 1'b0; #5 a = 8'b0000_1100; b = 8'b0000_0011; cin = 1'b0; #5 a = 8'b0000_0111; b = 8'b0000_0110; cin = 1'b1; #5 a = 8'b0001_1001; //25 (19h) b = 8'b0010_0111; //39 (27h) cin = 1'b1; //1. sum = 65 (41h) #5 a = 8'b0111_1101; //125 (7dh) b = 8'b0110_0111; //103 (67h) cin = 1'b1; //1. sum = 229 (e5h) #5 a = 8'b1000_1111; //143 (8fh) b = 8'b1100_0110; //198 (c6h) cin = 1'b1; //1. sum = 342 (156h) #5 $stop; //instantiate the module into the test bench param1 inst1 (.a(a),.b(b),.cin(cin),.sum(sum) ); Figure 4.3 (Continued)
Chapter 4 Expressions 4 Page 122 a b cin = 00000011_00000100_0, sum = 000000111 a b cin = 00001100_00000011_0, sum = 000001111 a b cin = 00000111_00000110_1, sum = 000001110 a b cin = 00011001_00100111_1, sum = 001000001 a b cin = 01111101_01100111_1, sum = 011100101 a b cin = 10001111_11000110_1, sum = 101010110 Figure 4.4 Outputs obtained from the test bench of Figure 4.3. Figure 4.5 Data analyzer waveforms for the test bench of Figure 4.4.
Chapter 4 Expressions 5 Page 128 //demonstrate arithmetic operations module arith_ops1 (a, b, opcode, rslt); input [3:0] a, b; input [2:0] opcode; output [7:0] rslt; reg [7:0] rslt; parameter addop = 3'b000, subop = 3'b001, mulop = 3'b010, divop = 3'b011, modop = 3'b100; always @ (a or b or opcode) case (opcode) addop: rslt = a + b; subop: rslt = a - b; mulop: rslt = a * b; divop: rslt = a / b; modop: rslt = a % b; default: rslt = 8 bxxxxxxxx; case Figure 4.7 Verilog code illustrating the operations of addition, subtraction, multiplication, division, and modulus. //arithmetic operations test bench module arith_ops1_tb; reg [3:0] a, b; reg [2:0] opcode; wire [7:0] rslt ; //continued on next page Figure 4.8 Test bench for the module of Figure 4.7.
Chapter 4 Expressions 6 $monitor ("a = %b, b = %b, opcode = %b, rslt = %b", a, b, opcode, rslt); #0 a = 4'b0011; b = 4'b0111; opcode = 3'b000; #5 a = 4'b1111; b = 4'b1111; opcode = 3'b001; #5 a = 4'b1110; b = 4'b1110; opcode = 3'b010; #5 a = 4'b1000; b = 4'b0010; opcode = 3'b011; #5 a = 4'b0111; b = 4'b0011; opcode = 3'b100; #5 $stop; //instantiate the module into //the test bench arith_ops1 inst1 (.a(a),.b(b),.opcode(opcode),.rslt(rslt) ); Figure 4.8 (Continued) Page 129 a = 0011, b = 0111, opcode = 000, rslt = 00001010 a = 1111, b = 1111, opcode = 001, rslt = 00000000 a = 1110, b = 1110, opcode = 010, rslt = 11000100 a = 1000, b = 0010, opcode = 011, rslt = 00000100 a = 0111, b = 0011, opcode = 100, rslt = 00000001 //add //subtract //multiply //divide //modulus Figure 4.9 Outputs for the test bench of Figure 4.8.
Chapter 4 Expressions 7 Page 130 Figure 4.10 Waveforms for the test bench of Figure 4.8. Page 130 //examples of logical operators module log_ops1 (a, b, z1, z2, z3); input [3:0] a, b; output z1, z2, z3; assign z1 = a && b; assign z2 = a b; assign z3 =!a; Figure 4.11 Examples of logical operators.
Chapter 4 Expressions 8 Page 131 //test bench for logical //operators module log_ops1_tb; reg [3:0] a, b; wire z1, z2, z3; $monitor ("z1 = %d, z2 = %d, z3 = %d", z1, z2, z3); //apply input vectors #0 a = 4'b0110; b = 4'b1100; #5 a = 4'b0101; b = 4'b0000; #5 a = 4'b1000; b = 4'b1001; #5 a = 4'b0000; b = 4'b0000; #5 a = 4'b1111; b = 4'b1111; #5 $stop; //instantiate the module //into the test bench log_ops1 inst1 (.a(a),.b(b),.z1(z1),.z2(z2),.z3(z3) ); Figure 4.12 Test bench for the logical operators module. z1 = 1, z2 = 1, z3 = 0 z1 = 0, z2 = 1, z3 = 0 z1 = 1, z2 = 1, z3 = 0 z1 = 0, z2 = 0, z3 = 1 z1 = 1, z2 = 1, z3 = 0 //z1 is logical AND //z2 is logical OR //z3 is logical negation Figure 4.13 Outputs for the logical operators obtained from the test bench of Figure 4.12. Output z 1 is the logical AND; output z 2 is the logical OR; output z 3 is the logical negation.
Chapter 4 Expressions 9 Page 132 Figure 4.14 Waveforms for the logical operators obtained from the test bench of Figure 4.12. Output z 1 is the logical AND; output z 2 is the logical OR; output z 3 is the logical negation. Pagw 133 //examples of relational operators module relational_ops1 (a, b, gt, lt, gte, lte); input [3:0] a, b; output gt, lt, gte, lte; assign gt = a > b; assign lt = a < b; assign gte = a >= b; assign lte = a <= b; Figure 4.15 Verilog module to illustrate the relational operators.
Chapter 4 Expressions 10 Page 133 //test bench relational ops module relational_ops1_tb; reg [3:0] a, b; wire gt, lt, gte, lte; $monitor ("a=%b, b=%b, gt=%d, lt=%d, gte=%d, lte=%d", a, b, gt, lt, gte, lte); b = 4'b1001; #5 a = 4'b0000; b = 4'b0000; #5 a = 4'b1111; b = 4'b1111; #5 $stop; //instantiate the module relational_ops1 inst1 (.a(a),.b(b),.gt(gt),.lt(lt),.gte(gte),.lte(lte) ); //apply input vectors #0 a = 4'b0110; b = 4'b1100; #5 a = 4'b0101; b = 4'b0000; #5 a = 4'b1000; Figure 4.16 Test bench for the relational operators module of Figure 4.15. Page 134 a=0110, b=1100, gt=0, lt=1, gte=0, lte=1 a=0101, b=0000, gt=1, lt=0, gte=1, lte=0 a=1000, b=1001, gt=0, lt=1, gte=0, lte=1 a=0000, b=0000, gt=0, lt=0, gte=1, lte=1 a=1111, b=1111, gt=0, lt=0, gte=1, lte=1 Figure 4.17 Outputs for the test bench of Figure 4.16 for the relational operators. Figure 4.18 Waveforms for the test bench of Figure 4.16 for the relational operators.
Chapter 4 Expressions 11 Page 135 //illustrate the use of equality operators module equality (x1, x2, x3, x4, x5, z1, z2, z3, z4); input [3:0] x1, x2, x3, x4, x5; output z1, z2, z3, z4; wire x1, x2, x3, x4, x5; //z1 is logical equality //z2 is logical inequality //z3 is case equality //z4 is case inequality reg z1, z2, z3, z4; //can be omitted. //inputs are wire by default always @ (x1 or x2 or x3 or x4 or x5) if (x1 == x2) //logical equality z1 = 1; else z1 = 0; always @ (x1 or x2 or x3 or x4 or x5) if (x2!= x3) //logical inequality z2 = 1; else z2 = 0; always @ (x1 or x2 or x3 or x4 or x5) if (x3 === x4) //case equality z3 = 1; else z3 = 0; always @ (x1 or x2 or x3 or x4 or x5) if (x4!== x5) z4 = 1; else z4 = 0; Figure 4.19 Module to illustrate the use of the equality operators.
Chapter 4 Expressions 12 Page 136 //equality operators test bench module equality_tb; reg [3:0] x1, x2, x3, x4, x5; wire z1, z2, z3, z4; $monitor ("x1=%b, x2=%b, x3=%b, x4=%b, x5=%b, z1=%b, z2=%b, z3=%b, z4=%b", x1, x2, x3, x4, x5, z1, z2, z3, z4); //apply input vectors #0 x1 = 4'b1000; x2 = 4'b1101; x3 = 4'b01xz; x4 = 4'b01xz; x5 = 4'bx1xx; #10 x1 = 4'b1011; x2 = 4'b1011; x3 = 4'bx1xz; x4 = 4'bx1xz; x5 = 4'b11xx; #10 x1 = 4'b1100; x2 = 4'b0101; x3 = 4'bx10z; x4 = 4'b11xz; x5 = 4'b11xx; //instantiate the module into the test bench equality inst1 (.x1(x1),.x2(x2),.x3(x3),.x4(x4),.x5(x5),.z1(z1),.z2(z2),.z3(z3),.z4(z4) ); Figure 4.20 Test bench for the equality module of Figure 4.19.
Chapter 4 Expressions 13 Page 137 x1=1000, x2=1101, x3=01xz, x4=01xz, x5=x1xx, z1=0, z2=1, z3=1, z4=1 x1=1011, x2=1011, x3=x1xz, x4=x1xz, x5=11xx, z1=1, z2=1, z3=1, z4=1 x1=1100, x2=0101, x3=x01z, x4=11xz, x5=11xx, z1=0, z2=1, z3=0, z4=1 Outputs for the test bench of Figure 4.20 for the equality module of Fig- Figure 4.21 ure 4.19. Page 141 //example of the bitwise operators module bitwise1 (a, b, and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt); input [7:0] a, b; output [7:0] and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt; wire [7:0] a, b; reg [7:0] and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt; always @ (a or b) and_rslt = a & b; or_rslt = a b; neg_rslt = ~a; xor_rslt = a ^ b; xnor_rslt = a ^~ b; //bitwise AND //bitwise OR //bitwise negation //bitwise exclusive-or //bitwise exclusive-nor Figure 4.22 Module to illustrate the coding for the bitwise operators.
Chapter 4 Expressions 14 Page 142 //test bench for bitwise1 module module bitwise1_tb; reg [7:0] a, b; wire [7:0] and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt; $monitor ("a=%b, b=%b, and_rslt=%b, or_rslt=%b, neg_rslt=%b, xor_rslt=%b, xnor_rslt=%b", a, b, and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt); $monitor ("a=%b, b=%b, and_rslt=%b, or_rslt=%b, neg_rslt=%b, xor_rslt=%b, xnor_rslt=%b", a, b, and_rslt, or_rslt, neg_rslt, xor_rslt, xnor_rslt); //apply input vectors #0 a = 8'b1100_0011; b = 8'b1001_1001; #10 a = 8'b1001_0011; b = 8'b1101_1001; #10 a = 8'b0000_1111; b = 8'b1101_1001; #10 a = 8'b0100_1111; b = 8'b1101_1001; #10 a = 8'b1100_1111; b = 8'b1101_1001; #10 $stop; //instantiate the module into the test bench bitwise1 inst1 (.a(a),.b(b),.and_rslt(and_rslt),.or_rslt(or_rslt),.neg_rslt(neg_rslt),.xor_rslt(xor_rslt),.xnor_rslt(xnor_rslt) ); Figure 4.23 Test bench for the bitwise module of Figure 4.22.
Chapter 4 Expressions 15 Page 143 a = 11000011, b = 10011001, and_rslt = 10000001, or_rslt = 11011011, neg_rslt = 00111100, xor_rslt = 01011010, xnor_rslt= 10100101 a = 10010011, b = 11011001, and_rslt = 10010001, or_rslt = 11011011, neg_rslt = 01101100, xor_rslt = 01001010, xnor_rslt= 10110101 a = 00001111, b = 11011001, a = 01001111, b = 11011001, and_rslt = 01001001, or_rslt = 11011111, neg_rslt = 10110000, xor_rslt = 10010110, xnor_rslt= 01101001 a = 11001111, b = 11011001, and_rslt = 11001001, or_rslt = 11011111, neg_rslt = 00110000, xor_rslt = 00010110, xnor_rslt= 11101001 and_rslt = 00001001, or_rslt = 11011111, neg_rslt = 11110000, xor_rslt = 11010110, xnor_rslt= 00101001 Figure 4.24 Outputs for the bitwise module of Figure 4.22.
Chapter 4 Expressions 16 Page 145 //module to illustrate the use of reduction operators module reduction (a, and_rslt, nand_rslt, or_rslt, nor_rslt, xor_rslt, xnor_rslt); input [7:0] a; output and_rslt, nand_rslt, or_rslt, nor_rslt, xor_rslt, xnor_rslt; wire [7:0] a; reg and_rslt, nand_rslt, or_rslt, nor_rslt, xor_rslt, xnor_rslt; always @(a) and_rslt = &a; nand_rslt = ~&a; or_rslt = a; nor_rslt = ~ a; xor_rslt = ^a; xnor_rslt = ^~a; //reduction AND //reduction NAND //reduction OR //reduction NOR //reduction exclusive-or //reduction exclusive-nor Figure 4.25 Module to illustrate the use of the reduction operators. //test bench for reduction module module reduction_tb; reg [7:0] a; wire and_rslt, nand_rslt, or_rslt, nor_rslt, xor_rslt, xnor_rslt; $monitor ("a=%b, and_rslt=%b, nand_rslt=%b, or_rslt=%b, nor_rslt=%b, xor_rslt=%b, xnor_rslt=%b", a, and_rslt, nand_rslt, or_rslt, nor_rslt, xor_rslt, xnor_rslt); //continued on next page Figure 4.26 Test bench for the reduction operators of Figure 4.25.
Chapter 4 Expressions 17 //apply input vectors #0 a = 8'b1100_0011; #10 a = 8'b1001_0011; #10 a = 8'b0000_1111; #10 a = 8'b0100_1111; #10 a = 8'b1100_1111; #10 $stop; //instantiate the module into the test bench reduction inst1 (.a(a),.and_rslt(and_rslt),.nand_rslt(nand_rslt),.or_rslt(or_rslt),.nor_rslt(nor_rslt),.xor_rslt(xor_rslt),.xnor_rslt(xnor_rslt) ); Figure 4.26 (Continued) a=11000011, and_rslt=0,nand_rslt=1,or_rslt=1,nor_rslt=0, xor_rslt=0,xnor_rslt=1 a=10010111, and_rslt=0,nand_rslt=1,or_rslt=1,nor_rslt=0, xor_rslt=1,xnor_rslt=0 a=00000000, and_rslt=0,nand_rslt=1,or_rslt=0,nor_rslt=1, xor_rslt=0,xnor_rslt=1 a=01001111, and_rslt=0,nand_rslt=1,or_rslt=1,nor_rslt=0, xor_rslt=1,xnor_rslt=0 a=11111111, and_rslt=1,nand_rslt=0,or_rslt=1,nor_rslt=0, xor_rslt=0,xnor_rslt=1 Figure 4.27 Outputs for the reduction operators of Figure 4.25.
Chapter 4 Expressions 18 Page 147 //examples of shift operations module shift (a_reg, b_reg, rslt_a, rslt_b); input [7:0] a_reg, b_reg; output [7:0] rslt_a, rslt_b; wire [7:0] a_reg, b_reg; reg [7:0] rslt_a, rslt_b; always @ (a_reg or b_reg) rslt_a = a_reg << 3; //multiply by 8 rslt_b = b_reg >> 2; //divide by 4 Figure 4.28 Examples of shift-left and shift-right operators.
Chapter 4 Expressions 19 Page 148 //shift test bench module shift_tb; reg [7:0] a_reg, b_reg; wire [7:0] rslt_a, rslt_b; //display variables $monitor ("a_reg = %b, b_reg = %b, rslt_a = %b, rslt_b = %b", a_reg, b_reg, rslt_a, rslt_b); //apply input vectors #0 a_reg = 8'b0000_0010; //2; rslt_a = 16 b_reg = 8'b0000_1000; //8; rslt_b = 2 #10 a_reg = 8'b0000_0110; //6; rslt_a = 48 b_reg = 8'b0001_1000; //24; rslt_b = 6 #10 a_reg = 8'b0000_1111; //15; rslt_a = 120 b_reg = 8'b0011_1000; //56; rslt_b = 14 #10 a_reg = 8'b1110_0000; //224; rslt_a = 0 b_reg = 8'b0000_0011; //3; rslt_b = 0 #10 $stop; //instantiate the module into the test bench shift inst1 (.a_reg(a_reg),.b_reg(b_reg),.rslt_a(rslt_a),.rslt_b(rslt_b) ); Figure 4.29 Test bench for the shift operators of Figure 4.28.
Chapter 4 Expressions 20 Page 149 a_reg = 00000010, b_reg = 00001000, //shift a_reg left 3 rslt_a = 00010000, rslt_b = 00000010 //shift b_reg right 2 a_reg = 00000110, b_reg = 00011000, //shift a_reg left 3 rslt_a = 00110000, rslt_b = 00000110 //shift b_reg right 2 a_reg = 00001111, b_reg = 00111000, //shift a_reg left 3 rslt_a = 01111000, rslt_b = 00001110 //shift b_reg right 2 a_reg = 11100000, b_reg = 00000011, //shift a_reg left 3 rslt_a = 00000000, rslt_b = 00000000 //shift b_reg right 2 Figure 4.30 Outputs for the test bench of Figure 4.29 showing the results of the shiftleft and shift-right operations. Operand a_reg is shifted left three bits with the low-order bits filled with zeroes. Operand b_reg is shifted right two bits with the high-order bits filled with zeroes. Page 150 //dataflow 2:1 mux using conditional operator module mux_2to1_cond (s0, in0, in1, out); input s0, in0, in1; output out; assign out = s0? in1 : in0; // s0 out // 1(true) in1 // 0(false) in0 Figure 4.31 Verilog code to model a 2:1 multiplexer using the conditional operator.
Chapter 4 Expressions 21 Page 151 //2:1 multiplexer test bench module mux_2to1_cond_tb; reg s0, in0, in1; wire out; //display variables $monitor ("s0=%b, in0 in1=%b, out = %b", s0, {in0, in1}, out); //apply stimulus #0 s0 = 1'b0; in0 = 1'b0; in1 = 1'b0; #10 s0 = 1'b0; in0 = 1'b1; in1 = 1'b1; #10 s0 = 1'b1; in0 = 1'b1; in1 = 1'b0; #10 s0 = 1'b1; in0 = 1'b0; in1 = 1'b1; #10 $stop; //instantiate the module //into the test bench mux_2to1_cond inst1 (.s0(s0),.in0(in0),.in1(in1),.out(out) ); Figure 4.32 Test bench for the 2:1 multiplexer of Figure 4.31. s0 = 0, in0 in1 = 00, out = 0 s0 = 0, in0 in1 = 11, out = 1 s0 = 1, in0 in1 = 10, out = 0 s0 = 1, in0 in1 = 01, out = 1 Figure 4.33 Outputs for the test bench of Figure 4.32.
Chapter 4 Expressions 22 Page 152 //examples of concatenation module concat (a, b, c, d, a_bus, z1, z2, z3, z4, z5, z6); input [1:0] a; input [2:0] b; input [3:0] c; input d; input [7:0] a_bus; output [9:0] z1, z2, z3, z4; output [7:0] z5; output [11:0] z6; assign z1 = {a, c}; assign z2 = {b, a}; assign z3 = {c, b, a}; assign z4 = {a, b, c, d}; assign z5 = {a_bus[3:0], a_bus[7:4]}; assign z6 = {b, c, d, 4 b0111}; Figure 4.34 Verilog module to demonstrate the use of the concatenation operator. //concatenation test bench module concat_tb; reg [1:0]a; reg [2:0]b; reg [3:0]c; reg d; reg [7:0] a_bus; wire [7:0] z5; wire [9:0] z1, z2, z3, z4; wire [11:0] z6; $monitor ("a=%b, b=%b, c=%b, d=%b, z1=%b, z2=%b, z3=%b, z4=%b, z5=%b, z6=%b", a, b, c, d, z1, z2, z3, z4, z5, z6); //continued on next page Figure 4.35 Test bench for the concatenation module of Figure 4.34.
Chapter 4 Expressions 23 #0 a = 2'b11; b = 3'b001; c = 4'b1100; d = 1'b1; a_bus = 8'b1111_0000; #10 $stop; //instantiate the module into the test bench concat inst1 (.a(a),.b(b),.c(c),.d(d),.a_bus(a_bus),.z1(z1),.z2(z2),.z3(z3),.z4(z4),.z5(z5),.z6(z6) ); Figure 4.35 (Continued) z1, z2, z3, and z4 are 10 bits in length. a = 11, b = 001, c = 1100, d = 1 a_bus = 11110000 z1 = 0000_11_1100 //z1 = {a, c} z2 = 00000_001_11 //z2 = {b, a} z3 = 0_1100_001_11 //z3 = {c, b, a} z4 = 11_001_1100_1 //z4 = {a, b, c, d} z5 = 0000_1111 //z5 = {a_bus [3:0], a_bus [7:4]} z6 = 001_1100_1_0111 //z6 = {b, c, d, 4 b0111} Figure 4.36 Outputs for the concatenation test bench of Figure 4.35.
Chapter 4 Expressions 24 Page 154 //example of replication module replication (a, b, c, z1, z2); input [1:0] a; input [2:0] b; input [3:0] c; output [11:0] z1; output [21:0] z2; assign z1 = {2{a, c}}; assign z2 = {2{b, c, 4'b0111}}; Figure 4.37 Module to illustrate the replication operator.
Chapter 4 Expressions 25 Page 155 //replication test bench module replication_tb; reg [1:0] a; reg [2:0] b; reg [3:0] c; wire [11:0] z1; wire [21:0] z2; $monitor ("a=%b, b=%b, c=%b, z1=%b, z2=%b", a, b, c, z1, z2); #0 a = 2'b11; b = 3'b010; c = 4'b0011; #10 $stop; //instantiate the module into the test bench replication inst1 (.a(a),.b(b),.c(c),.z1(z1),.z2(z2) ); Figure 4.38 Test bench for the replication module of Figure 4.37. Page 156 a = 11, b = 010, c = 0011, z1 = 11_0011_11_0011, //z1 = {2{a, c}} z2 = 010_0011_0111_010_0011_0111 //z2 = {2{b, c, 4'b0111}} Figure 4.39 Outputs for the replication test bench of Figure 4.38.