Combinational Logic with Verilog Materials taken from: Digital Design and Computer Architecture by David and Sarah Harris & The Essentials of Computer Organization and Architecture by L. Null & J. Lobur 3.5 Combinational Circuits • Combinational logic circuits give us many useful devices. • One of the simplest is the half adder, which finds the sum of two bits. • We can gain some insight as to the construction of a half adder by looking at its truth table, shown at the right. 2 3.5 Combinational Circuits • As we see, the sum can be found using the XOR operation and the carry using the AND operation. 3 3.5 Combinational Circuits • We can change our half adder into to a full adder by including gates for processing the carry bit. • The truth table for a full adder is shown at the right. 4 3.5 Combinational Circuits • Here’s our completed full adder. 5 3.5 Combinational Circuits • Just as we combined half adders to make a full adder, full adders can connected in series. • The carry bit “ripples” from one adder to the next; hence, this configuration is called a ripple-carry adder. Today’s systems employ more efficient adders. 6 3.5 Combinational Circuits • Decoders are another important type of combinational circuit. • Among other things, they are useful in selecting a memory location according a binary value placed on the address lines of a memory bus. • Address decoders with n inputs can select any of 2n locations. This is a block diagram for a decoder. 7 3.5 Combinational Circuits • This is what a 2-to-4 decoder looks like on the inside. If x = 0 and y = 1, which output line is enabled? 8 3.5 Combinational Circuits • A multiplexer does just the opposite of a decoder. • It selects a single output from several inputs. • The particular input chosen for output is determined by the value of the multiplexer’s control lines. • To be able to select among n inputs, log2n control lines are needed. This is a block diagram for a multiplexer. 9 3.5 Combinational Circuits • This is what a 4-to-1 multiplexer looks like on the inside. If S0 = 1 and S1 = 0, which input is transferred to the output? 10 3.5 Combinational Circuits • This shifter moves the bits of a nibble one position to the left or right. If S = 0, in which direction do the input bits shift? 11 Verilog Demo: Full Adder module fadd( output co, s, input ci, a, b ); wire a_xor_b; wire a_and_b; wire ci_and_a_xor_b; // common gate for both co and s xor u1( a_xor_b, a, b ); // remaining gates for co and u2( a_and_b, a, b ); and u3( ci_and_a_xor_b, ci, a_xor_b ); or u4( co, a_and_b, ci_and_a_xor_b ); // remaining gate for s xor u5( s, ci, a_xor_b ); endmodule 12 Demo Materials • Verilog Files: – fadd.v – fadd_tb.v – fadd_b.v – fadd_4bit.v – fadd_4bit_tb.v • ModelSim Resources: – ModelSimGUIIntro.pdf – TestbenchPrimer.pdf – ModelSimTutorial.pdf • Verilog Resource: – VerilogWiki – Verilog Quick Reference Introduction HDL • Hardware description language (HDL): allows designer to specify logic function only. Then a computer-aided design (CAD) tool produces or synthesizes the optimized gates. • Most commercial designs built using HDLs • Two leading HDLs: – Verilog • developed in 1984 by Gateway Design Automation • became an IEEE standard (1364) in 1995 – VHDL • Developed in 1981 by the Department of Defense • Became an IEEE standard (1076) in 1987 Copyright © 2007 Elsevier 4-<14> HDL to Gates • Simulation – Input values are applied to the circuit – Outputs checked for correctness – Millions of dollars saved by debugging in simulation instead of hardware • Synthesis – Transforms HDL code into a netlist describing the hardware (i.e., a list of gates and the wires connecting them) IMPORTANT: When describing circuits using an HDL, it’s critical to think of the hardware the code should produce. Copyright © 2007 Elsevier 4-<15> Verilog Modules a b c Verilog Module y Two types of Modules: – Behavioral: describe what a module does – Structural: describe how a module is built from simpler modules Copyright © 2007 Elsevier 4-<16> Behavioral Verilog Example Verilog: module example(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & endmodule Copyright © 2007 Elsevier 4-<17> c; Behavioral Verilog Simulation Verilog: module example(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & endmodule Copyright © 2007 Elsevier 4-<18> c; Behavioral Verilog Synthesis Verilog: module example(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & endmodule Synthesis: b c y un5_y y a un8_y Copyright © 2007 Elsevier 4-<19> c; Verilog Syntax • Case sensitive – Example: reset and Reset are not the same signal. • No names that start with numbers – Example: 2mux is an invalid name. • Whitespace ignored • Comments: – // single line comment – /* multiline comment */ Copyright © 2007 Elsevier 4-<20> Structural Modeling - Hierarchy module and3(input a, b, c, output y); assign y = a & b & c; endmodule module inv(input a, output y); assign y = ~a; endmodule module nand3(input a, b, c output y); wire n1; // internal signal and3 andgate(a, b, c, n1); // instance of and3 inv inverter(n1, y); // instance of inverter endmodule Copyright © 2007 Elsevier 4-<21> Bitwise Operators module gates(input [3:0] a, b, output [3:0] y1, y2, y3, y4, y5); /* Five different two-input logic gates acting on 4 bit busses */ assign y1 = a & b; // AND assign y2 = a | b; // OR assign y3 = a ^ b; // XOR assign y4 = ~(a & b); // NAND assign y5 = ~(a | b); // NOR endmodule // single line comment /*…*/ multiline comment Copyright © 2007 Elsevier 4-<22> Reduction Operators module and8(input [7:0] a, output y); assign y = &a; // &a is much easier to write than // assign y = a[7] & a[6] & a[5] & a[4] & // a[3] & a[2] & a[1] & a[0]; endmodule Copyright © 2007 Elsevier 4-<23> Conditional Assignment module mux2(input [3:0] d0, d1, input s, output [3:0] y); assign y = s ? d1 : d0; endmodule ? : is also called a ternary operator because it operates on 3 inputs: s, d1, and d0. Copyright © 2007 Elsevier 4-<24> Internal Variables module fulladder(input a, b, cin, output s, cout); wire p, g; // internal nodes assign p = a ^ b; assign g = a & b; assign s = p ^ cin; assign cout = g | (p & cin); endmodule s g s cin cout a b Copyright © 2007 Elsevier p un1_cout 4-<25> cout Precedence Defines the order of operations Highest ~ NOT *, /, % mult, div, mod +, - add,sub <<, >> shift <<<, >>> arithmetic shift <, <=, >, >= comparison Lowest ==, != equal, not equal &, ~& AND, NAND ^, ~^ XOR, XNOR |, ~| OR, XOR ?: ternary operator Copyright © 2007 Elsevier 4-<26> Numbers Format: N'Bvalue N = number of bits, B = base N'B is optional but recommended (default is decimal) Number # Bits Base Decimal Equivalent Stored 3’b101 3 binary 5 101 ‘b11 unsized binary 3 00…0011 8’b11 8 binary 3 00000011 8’b1010_1011 8 binary 171 10101011 3’d6 3 decimal 6 110 6’o42 6 octal 34 100010 8’hAB 8 hexadecimal 171 10101011 42 Unsized decimal 42 00…0101010 Copyright © 2007 Elsevier 4-<27> Bit Manipulations: Example 1 assign y = {a[2:1], {3{b[0]}}, a[0], 6’b100_010}; // if y is a 12-bit signal, the above statement produces: y = a[2] a[1] b[0] b[0] b[0] a[0] 1 0 0 0 1 0 // underscores (_) are used for formatting only to make it easier to read. Verilog ignores them. Copyright © 2007 Elsevier 4-<28> Bit Manipulations: Example 2 Verilog: module mux2_8(input [7:0] d0, d1, input s, output [7:0] y); mux2 lsbmux(d0[3:0], d1[3:0], s, y[3:0]); mux2 msbmux(d0[7:4], d1[7:4], s, y[7:4]); endmodule Synthesis: mux2 s s d0[7:0] [7:0] [3:0] d0[3:0] d1[7:0] [7:0] [3:0] d1[3:0] y[3:0] [3:0] lsbmux mux2 s Copyright © 2007 Elsevier [7:4] d0[3:0] [7:4] d1[3:0] y[3:0] msbmux 4-<29> [7:4] [7:0] y[7:0] Z: Floating Output Verilog: module tristate(input [3:0] a, input en, output [3:0] y); assign y = en ? a : 4'bz; endmodule Synthesis: en a[3:0] [3:0] [3:0] [3:0] y_1[3:0] Copyright © 2007 Elsevier 4-<30> [3:0] y[3:0] Delays module example(input a, b, c, output y); wire ab, bb, cb, n1, n2, n3; assign #1 {ab, bb, cb} = ~{a, b, c}; assign #2 n1 = ab & bb & cb; assign #2 n2 = a & bb & cb; assign #2 n3 = a & bb & c; assign #4 y = n1 | n2 | n3; endmodule Copyright © 2007 Elsevier 4-<31> Delays module example(input a, b, c, output y); wire ab, bb, cb, n1, n2, n3; assign #1 {ab, bb, cb} = ~{a, b, c}; assign #2 n1 = ab & bb & cb; assign #2 n2 = a & bb & cb; assign #2 n3 = a & bb & c; assign #4 y = n1 | n2 | n3; endmodule Copyright © 2007 Elsevier 4-<32>