ENEE 408C Lab Capstone Project: Digital System Design Spring 2006 Class Web Site: http://www.ece.umd.edu/class/enee408c TA’s Information Alessandro Geist ageist@umd.edu Office Hours: TBD Submission Format For Homework, Quiz, or Project Submission of source code, please name your verilog files: ageistquiz1df.v ageistquiz1tb.v // design file // test bench Submission Format For Homework, Quiz, or Project Submission of source code, please provide the following header in your verilog code: /*************************************************************** Author: Alessandro Geist Date: 09/02/2005 Assignment: Homework 1 Module: fourbitadder Submodules: halfAdder, fullAdder Description: This is a four-bit adder, it takes two four bit numbers and outputs the sum and carry. *****************************************************************/ Behavioral vs. Structural Description Structural Description – – – – a Verilog description of schematic easy to synthesize like gate-level netlist less readable from human’s point of view. Behavioral Description – – – – a description of the functionality flexible and more readable suitable for large scale design not always synthesizable Structural Description primitive instantiation (AND, NAND, OR, NOR, XOR, XNOR, BUF, NOT, BUFIF, NOTIF) parameter value assignment Example: Half Adder module halfAdder (SUM, CARRY, A,B); input A, B; output SUM, CARRY; XOR (SUM, A,B); // exclusive OR AND (CARRY, A,B); endmodule Behavioral Description Boolean expression level – continuous assignment Register transfer level (RTL) – procedural statement Algorithm description – for, while loops etc. – case, if else statements etc. Example: Half Adder module halfAdder (SUM, CARRY,A,B); input A, B; output SUM, CARRY; assign SUM = A ^ B; // exclusive OR assign CARRY = A & B; endmodule Full Adder Try Full Adder! Full Adder, composed of HA’s /*************************** FULL ADDER *********************************/ // fullAdder module definition - contains two instances of module halfAdder needed to create the fullAdder module fullAdder (SUM, CARRY_OUT, A_in, B_in, CARRY_IN); input output wire A_in, B_in, CARRY_IN; SUM, CARRY_OUT; w1, w2, w3; halfAdder H1(w1,w2, A_in, B_in); // instance of halfAdder module called H1 halfAdder H2(SUM, w3, CARRY_IN, w1); // instance of halfAdder called H2 OR o1 (CARRY_OUT, w2, w3); endmodule /******************************************************************************/ Using a Testbench Allows you to test the functionality of your design by applying test inputs and observing the outputs. When using Modelsim, must be in a separate .v file Must match the interface of your design Need not to be synthesizable. Full Adder Testbench `timescale 1ns / 1ps module tb_fulladder; wire SUM, CARRY_OUT; reg A_in, B_in, CARRY_IN; fullAdder instance1(SUM, CARRY_OUT, A_in, B_in, CARRY_IN); initial begin $monitor ($time,,, "A = %b B = %b C = %b SUM = %b, Cout = %b", A_in, B_in, CARRY_IN, SUM, CARRY_OUT); //TEST INPUTS #10 A_in=0; B_in=0; CARRY_IN=0; #10 A_in = 1; #10 CARRY_IN = 1; B_in = 1; end endmodule Vectors Vectors can be declared as [highbit:lowbit] or [lowbit:highbit] The leftmost number in the square brackets always corresponds to the most significant bit (as in extensions) When referencing a variable, range indices must be constants, but single indices can be variables Vectors in Verilog One dimension: define data with multiple bits. E.g. reg [15:0] sum; wire [15:0] w; assign w[3:0] = sum[15:12]; Two dimension: define a memory storage. E.g. reg [31:0] RegFile[31:0]; always@(posedge clk) RegFile[0] = 32’b0; Vector Examples reg [7:0] bus bus[4:0] The 5 least significant bits of bus wire [4:2] addends addends[3:2] The 2 least significant bits of addends wire [2:4] addends addends[2:3] The 2 most significant bits of addends reg [5:0] value value[var:1] Illegal — indices must be constant reg [5:0] value value[n] The nth bit of value where n is a register or a net Full Adder, composed of HA’s /*************************** FULL ADDER *********************************/ // fullAdder module definition - contains two instances of module halfAdder needed to create the fullAdder module fullAdder (SUM, CARRY_OUT, A_in, B_in, CARRY_IN); input output wire A_in, B_in, CARRY_IN; SUM, CARRY_OUT; [2:0] w; halfAdder H1(w[0],w[1], A_in, B_in); // instance of halfAdder module called H1 halfAdder H2(SUM, w[2], CARRY_IN, w[0]); // instance of halfAdder called H2 OR o1 (CARRY_OUT, w[1], w[2]); endmodule /******************************************************************************/ Numbers — Sized <size>’<base_format><value> – <size> is a decimal number and specifies the number of bits in the number. – <base_format> is one of [d/D] — Decimal [h/H] — Hex [b/B] — Binary [o/O] — Octal – <value> is a string of characters representing the number. Numbers — Sized : Examples 5’d3 = 00011 8’h0f = 00001111 7’b0 = 0000000 Numbers — Unsized Numbers specified without a <base_format> are decimal. – 4’7 = 0111 Numbers written without a <size> are simulator dependent — typically 32 bits. – ’hffff = 32’h0000ffff Combinational vs. Sequential Combinational – Combinations of logic where the outputs are only dependent on values of the current input signals – Combinational elements can be modeled using assign and always statements. Sequential – Outputs are dependent on values of the past inputs as well as current circuit inputs. – Sequential elements can be modeled using only always statements. Boolean Behavior and Continuous Assignment Define a Boolean equation that describes combinational logic by an expression of operations on variables. Left Hand Side must be of type wire, Right Hand Side can be reg or wire. E.g. wire sum; output c_out; assign #1 sum = a ^ b; assign #2 c_out = a & b; Cyclic Behavioral Models Model both level-sensitive behavior (combinational) and edge-sensitive behavior (flip-flop) of an element. always@ (a or b) begin sum = a ^ b; c_out = a & b; end always@ (posedge clk) dff_out <= dff_in; Blocking vs. Nonblocking In always blocks Blocking – Execute sequentially – Better for combinational logic Nonblocking – Execute Concurrently (in parallel) – Better for sequential logic – RHS of all statements calculated first from values before execution Combinational Examples of Blocking vs. Nonblocking Blocking Reg D, B; always @ (E or D) begin // D=2, E=5, B=3 initially D = E; // D=5 B = D; // B=5 end Nonblocking Reg D, B; always @ (E or D) begin // D=2, E=5, B=3 initially D <= E; // D=5 B <= D; // B=2 end