490 likes | 780 Views
Chapter 11. Verilog HDL. Application-Specific Integrated Circuits Michael John Sebastian Smith Addison Wesley, 1997. Verilog HDL. Verilog is an alternative hardware description language to VHDL developed by Gateway Design Automation
E N D
Chapter 11 Verilog HDL Application-Specific Integrated CircuitsMichael John Sebastian Smith Addison Wesley, 1997
Verilog HDL • Verilog is an alternative hardware description language to VHDL developed by Gateway Design Automation • Cadence purchased Gateway and placed Verilog in the public domain (Open Verilog International - OVI) • An IEEE standard version of Verilog was developed in 1995 [IEEE Std. 1364-1995 Verilog LRM] • In spite of this standardization, many flavors (usually vendor specific) of Verilog still persist • Verilog syntax is much like C • Verilog use is generally most prevalent on the West Coast (Silicon Valley) • Most high-end commercial simulators support both VHDL and Verilog and you may receive IP blocks for your designs in Verilog which you will be expected to be able to work with • OVI and VHDL International have recently merged further indicating a dual (or multi) language environment will become more prevalent
Verilog Identifiers • Identifiers (names of variables, wires, modules, etc.) can contain any sequence of letters, numbers, ‘$’, or ‘_’ • The first character of an identifier must be a letter or underscore • Verilog identifiers are case sensitive reg legal_identifier, two__underscores; reg _OK, OK_, OK_$, CASE_SENSITIVE, case_sensitive;
Verilog Logic Values and Data Types • Verilog has a predefined logic-value system or value set: • ‘0’, ‘1’, ‘x’, and ‘z’ • Verilog has a limited number of data types: • reg - like a variable, default value is ‘x’ and is updated immediately when on LHS of an assignment • net - can not store values between assignments; default value is ‘z’; has subtypes: • wire, tri • supply1, supply0 • integer • time • event • real
Verilog Data Types (cont.) • The default for a wire or reg is a scalar • Wires and reg’s may also be declared as vectors with a range of bits wire [31:0] Abus, Dbus; reg [7:0] byte; • A 2-dimensional array of registers can be declared for memories - larger dimensional arrays are not allowed reg [31:0] VideoRam [7:0]; // an 8-word by 32-bit wide memory
Verilog Numbers • Constants are written as: width’radix value • Radix is decimal (d or D), hex (h or H), octal (o or O), or binary (b or B) • Constants can be declared as parameters: parameter H12_UNSIZED = ‘h 12; parameter H12_SIZED = 8`h 12; parameter D8 = 8`b 0011_1010; parameter D4 = 4`b 0xz1 parameter D1 = 1`bx
Verilog Operators ?: (conditional) a ternary operator || (logical or) && (logical and) | (bitwise or) ~| (bitwise nor) ^ (bitwise xor) ^~ ~^ (bitwise xor) & (bitwise and) ~& (bitwise nand) == (logical equality) != (logical inequality) === (case equality) !== (case inequality) < (less than) <= (less than or equal) > (greater than) >= (greater than or equal) << (shift left) >> shift right + (addition) - (subtraction) * (multiply) / (divide) % (modulus) Unary operators: ! ~ & ~& | ~| ^ ~^ + -
Verilog Unary Operators ! logical negation ~ bitwise unary negation & unary reduction and ~& unary reduction nand | unary reduction or ~| unary reduction nor ^ unary reduction xor (parity) ~^ ^~ unary reduction xnor + unary plus - unary minus
Verilog Modules • The module is the basic unit of code in Verilog • corresponds to VHDL entity/architecture pair • Module interfaces must be explicitly declared to interconnect modules • ports must be declared as one of input, output, or inout • Modules have an implicit declarative part • Example also shows a continuous assignment statement module aoi221(A, B, C, D, E, F); output F; input A, B, C, D, E; assign F = ~((A & B) | (C & D) | E); endmodule
AOI221 simulation results • ModelSim can simulate Verilog and mixed-VHDL and Verilog models as well as pure VHDL models >>vlib work >>vlog aoi221.v >>vsim aoi221
Verilog Sequential Blocks • Sequential blocks appear between a begin and end • Assignments inside a sequential block must be to a reg • declaring a reg with the same name as a port “connects” them together • Sequential blocks may appear in an always statement • similar to a VHDL process • may have a sensitivity list module aoi221(A, B, C, D, E, F); output F; input A, B, C, D, E; reg F; always @(A or B or C or D or E) begin F = ~((A & B) | (C & D) | E); end endmodule
Verilog Delays • Delays are specified as a number (real or integer) preceded with a # sign • Delays are added to the assignment statement - position is important! • Sample RHS immediately and then delay assignment to the LHS • Delay for a specified time and then sample the RHS and assign to the LHS • Timescale compiler directive specifies the time units followed by the precision to be used to calculate time expressions `timescale 1ns/100ps module aoi221(A, B, C, D, E, F, G); output F, G; input A, B, C, D, E; reg F, G; always @(A or B or C or D or E) begin F = #2.5 ~((A & B) | (C & D) | E); end always @(A or B or C or D or E) begin #2 G = ~((A & B) | (C & D) | E); end endmodule
Non Blocking Assignments • The previous example used blocking assignments (the default) which caused the problem with F not being updated • Non-blocking assignments (<=) can be used to avoid this problem • Care must be used when mixing types of assignments and different delay models `timescale 1ns/100ps module aoi221(A, B, C, D, E, F, G); output F, G; input A, B, C, D, E; reg F, G; always @(A or B or C or D or E) begin F <= #2.5 ~((A & B) | (C & D) | E); end always @(A or B or C or D or E) begin #2 G <= ~((A & B) | (C & D) | E); end endmodule
Verilog Parameters • Parameters can be used to specify values as constants • Parameters can also be overwritten when the module is instantiated in another module • similar to VHDL generics `timescale 1ns/100ps module aoi221(A, B, C, D, E, F); parameter DELAY = 2; output F; input A, B, C, D, E; reg F; always @(A or B or C or D or E) begin #DELAY F = ~((A & B) | (C & D) | E); end endmodule
Verilog Parameters (cont.) • Parameters can be used to determine the “width” of inputs and outputs `timescale 1ns/100ps module aoi221_n(A, B, C, D, E, F); parameter N = 4; parameter DELAY = 4; output [N-1:0] F; input [N-1:0] A, B, C, D, E; reg [N-1:0] F; always @(A or B or C or D or E) begin #DELAY F = ~((A & B) | (C & D) | E); end endmodule
Initialization within Modules • In addition to the always statement, an initial statement can be included in a module • runs only once at the beginning of simulation • can include a sequential block with a begin and end `timescale 1ns/100ps module aoi221(A, B, C, D, E, F); parameter DELAY = 2; output F; input A, B, C, D, E; reg F; initial begin #DELAY; F=1; end always @(A or B or C or D or E) begin #DELAY F = ~((A & B) | (C & D) | E); end endmodule
Verilog if Statements • If statements can be used inside a sequential block `timescale 1ns/1ns module xor2(A, B, C); parameter DELAY = 2; output C; input A, B; reg C; always @(A or B) begin if ((A == 1 && B == 0) || (A == 0 && B == 1)) #DELAY assign C = 1; else if ((A == 0 && B == 0) || (A == 1 && B == 1)) #DELAY assign C = 0; else assign C = 1'bx; end endmodule
Verilog Loops • For, while, repeat, and forever loops are available • Must be inside a sequential block module aoi221_n(A, B, C, D, E, F); parameter N = 4; parameter DELAY = 4; output [N-1:0] F; input [N-1:0] A, B, C, D, E; reg [N-1:0] F; integer i; initial begin i = 0; while (i < N) begin F[i] = 0; i = i + 1; end end always @(A or B or C or D or E) begin for(i = 0; i < N; i = i+1) begin #DELAY F[i] = ~((A[i] & B[i]) | (C[i] & D[i]) | E[i]); end end endmodule
Verilog Case Statements • Case statements must be inside a sequential block • Casex (casez) statements handle ‘z’ and ‘x’ (only ‘z’) as don’t cares • Expressions can use ? To specify don’t cares `timescale 1ns/1ns module mux4(sel, d, y); parameter DELAY = 2; output y; input [1:0] sel ; input [3:0] d; reg y; always @(sel or d) begin case(sel) 2'b00: #DELAY y = d[0]; 2'b01: #DELAY y = d[1]; 2'b10: #DELAY y = d[2]; 2'b11: #DELAY y = d[3]; default: #DELAY y = 1'bx; endcase end endmodule
Verilog Primitives • Verilog has built-in primitives that can be used to model single output gates • The first port is the output and the remaining ports are the inputs • Implicit parameters for the output drive strength and delay are provided `timescale 1ns/1ns module aoi21(A, B, C, D); parameter DELAY = 2; output D; input A, B, C; wire sig1; and #DELAY and_1(sig1, A, B); nor #DELAY nor_1(D, sig1, C); endmodule
User-Defined Primitives • Verilog allows user-defined primitives for modeling single-output gates • Delay and drive strength is not defined in the primitive itself • A table is used to define the outputs • (? Signifies a don’t care) `timescale 1ns/1ns primitive AOI321(G, A, B, C, D, E, F); output G; input A, B, C, D, E, F; table ?????1 : 1; 111??? : 1; ???11? : 1; 0??0?0 : 0; ?0?0?0 : 0; ??00?0 : 0; 0???00 : 0; ?0??00 : 0; ??0?00 : 0; endtable endprimitive
Example Using New Primitive • Drive strength and delay can be included in “call” to primitive `timescale 1ns/1ns module aoi321(A, B, C, D, E, F, G); parameter DELAY = 2; output G; input A, B, C, D, E, F; AOI321 #DELAY aoi321_1(G, A, B, C, D, E, F); endmodule
A Sum B Cin Cout Verilog Structural Descriptions • The implementation of a full adder shown below will be realized using a structural description
Gates for Full Adder `timescale 1ns/1ns module xor2(A, B, C); parameter DELAY = 2; output C; input A, B; reg C; always @(A or B) begin if ((A == 1 && B == 0) || (A == 0 && B == 1)) #DELAY assign C = 1; else if ((A == 0 && B == 0) || (A == 1 && B == 1)) #DELAY assign C = 0; else assign C = 1'bx; end endmodule `timescale 1ns/1ns module and2(A, B, C); parameter DELAY = 2; output C; input A, B; reg C; always @(A or B) begin if (A == 1 && B == 1) #DELAY assign C = 1; else if (A == 0 || B == 0) #DELAY assign C = 0; else assign C = 1'bx; end endmodule `timescale 1ns/1ns module or3(A, B, C, D); parameter DELAY = 2; output D; input A, B, C; reg D; always @(A or B or C) begin if (A == 1 || B == 1 || C == 1) #DELAY assign D = 1; else if (A == 0 && B == 0 && C == 0) #DELAY assign D = 0; else assign D = 1'bx; end endmodule
Structural Description of Full Adder `timescale 1ns/100ps module fa(A, B, Cin, Sum, Cout); output Sum, Cout; input A, B, Cin; wire sig1, sig2, sig3, sig4; xor2 #2.5 xor_1(A, B, sig1), xor_2(sig1, Cin, Sum); and2 #1.25 and_1(A, B, sig2), and_2(A, Cin, sig3), and_3(B, Cin, sig4); or3 #2 or3_1(sig2, sig3, sig4, Cout); endmodule • Multiple instantiations can be made on one line • Parameter values for all instances are defined at the beginning of the line • Unique instance names must be specified
Modeling Sequential Hardware Devices in Verilog (flip-flops) • Note assign statement can be used (on a reg) within a sequential block • Deassign statement can be used to allow other writers to a signal • This module models a leading-edge triggered flip-flop with asynchronous preset and clear module dff_clr_pre(d, q, qn, _pre, _clr, clk); parameter DELAY = 2; output q, qn; input d, _pre, _clr, clk; reg q; always @(_pre or _clr) begin if (!_pre) #DELAY assign q = 1; else if (!_clr) #DELAY assign q = 0; else deassign q; end always @(posedge clk) #DELAY q = d; assign qn = ~q; endmodule
Modeling Flip-Flops (cont.) • This module models a leading-edge triggered flip-flop with synchronous preset and clear module dff_clr_pre(d, q, qn, _pre, _clr, clk); parameter DELAY = 2; output q, qn; input d, _pre, _clr, clk; reg q; always @(posedge clk) begin if (!_pre) #DELAY q = 1; else if (!_clr) #DELAY q = 0; else #DELAY q = d; end assign qn = ~q; endmodule
Idle Test Add Modeling State Machines in VerilogSimple Example State Diagram START=‘1’ Initialize Q0=‘0’ Q0=‘1’ Shift
Example State MachineVHDL Code • Entity • Architecture declarative part • Memory process LIBRARY ieee ; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; ENTITY control_unit IS PORT(clk : IN std_logic; q0 : IN std_logic; reset : IN std_logic; start : IN std_logic; a_enable : OUT std_logic; a_mode : OUT std_logic; c_enable : OUT std_logic; m_enable : OUT std_logic); END control_unit; ARCHITECTURE fsm OF control_unit IS CONSTANT delay : time := 5 ns ; TYPE state_type IS ( idle, init, test, add, shift); SIGNAL present_state, next_state : state_type ; BEGIN clocked : PROCESS(clk, reset) BEGIN IF (reset = '0') THEN present_state <= idle; ELSIF (clk'EVENT AND clk = '1') THEN present_state <= next_state; END IF; END PROCESS clocked;
Example State MachineVHDL Code (cont.) • Next state process • Output process output : PROCESS(present_state,start,q0) BEGIN -- Default Assignment a_enable <= '0' after delay; a_mode <= '0' after delay; c_enable <= '0' after delay; m_enable <= '0' after delay; -- State Actions CASE present_state IS WHEN init => a_enable <= '1' after delay; c_enable <= '1' after delay; m_enable <= '1' after delay; WHEN add => a_enable <= '1' after delay; c_enable <= '1' after delay; m_enable <= '1' after delay; WHEN shift => a_enable <= '1' after delay; a_mode <= '1' after delay; m_enable <= '1' after delay; WHEN OTHERS => NULL; END CASE; END PROCESS output; END fsm; nextstate : PROCESS(present_state,start,q0) BEGIN CASE present_state IS WHEN idle => IF(start='1') THEN next_state <= init; ELSE next_state <= idle; END IF; WHEN init => next_state <= test; WHEN test => IF(q0='1') THEN next_state <= add; ELSIF(q0='0') THEN next_state <= shift; ELSE next_state <= test; END IF; WHEN add => next_state <= shift; WHEN shift => next_state <= test; END CASE; END PROCESS nextstate;
Example State MachineVerilog Code • Module declarative part includes definition of state “constants” • Note synthesizable description of dff with asynchronous clear for state variables module control_unit_v(clk, q0, reset, start, a_enable, a_mode, c_enable, m_enable); parameter DELAY = 5; output a_enable, a_mode, c_enable, m_enable; input clk, q0, reset, start; reg a_enable, a_mode, c_enable, m_enable; reg [2:0] present_state, next_state; parameter [2:0] idle = 3'd0, init = 3'd1, test = 3'd2, add = 3'd3, shift = 3'd4; always @(posedge clk or negedge reset) // Clock block begin if (reset == 0) begin present_state = idle; end else begin present_state = next_state; end end // Clock block
Example State MachineVerilog Code (cont.) • Next state and output blocks always @(present_state) // Output block begin // Default Assignment a_enable = 0; a_mode = 0; c_enable = 0; m_enable = 0; // Assignment for states case (present_state) init: begin a_enable = 1; c_enable = 1; m_enable = 1; end add: begin a_enable = 1; c_enable = 1; m_enable = 1; end shift: begin a_enable = 1; a_mode = 1; m_enable = 1; end endcase end // Output block endmodule // Next state block always @(present_state or q0 or start) begin case (present_state) idle: if ((start==1)) next_state = init; else next_state = idle; init: next_state = test; test: if ((q0==1)) next_state = add; else if ((q0==0)) next_state = shift; else next_state = test; add: next_state = shift; shift: next_state = test; default: next_state = idle; endcase end // Next State Block
Modeling (Bi-directional) Tri-State Buffers in Verilog • Use ? operator in continuous assignment statement • Inout port used for connection to “bus” E module tri_buff(D, E, Y, PAD); output Y; input D, E; inout PAD; reg sig; assign PAD = E ? D : 1'bz; assign Y = PAD; endmodule D PAD Y module tri_test(); wire D1, D2, D3, E1, E2, E3, Y1, Y2, Y3, BUS; tri_buff tri_1(D1, E1, Y1, BUS), tri_2(D2, E2, Y2, BUS), tri_3(D3, E3, Y3, BUS); endmodule