The Verilog Hardware Description Language
GUIDELINES How to write HDL code:
GUIDELINES How NOT to write HDL code:
Think Hardware NOT Software Poorly written HDL code will either be: Unsynthesizable Functionally incorrect Lead to poor performance/area/power results
Conventions Verilog IS case sensitive Syntax is based on C CLOCK, clock and Clock are different Syntax is based on C but is interpreted differently
Verilog code basic structure module module_name (ports); input input_signals; output output_signals; inout bidirectional signals; wire wire_signals; reg register_type_variables; primitive/component (ports); concurrent/sequential assignments endmodule
Port types PORT DIRECTION SIGNAL TYPE - input -output -inout scalar ( input x; ) vector (input [WIDTH -1 : 0] x)
Module port declaration example (1/2) module and_gate (o, i1, i2); output o; input i1; input i2; endmodule
Module port declaration example (2/2) module adder (carry, sum, i1, i2); output carry; output [3:0] sum; input [3:0] i1, i2; endmodule
Example
Verilog Primitives Verilog primitives are models of common combinational logic gates Their functionality is built into the language and can be instantiated in designs directly The output port of a primitive must be first in the list of ports
Structural description example (implicit connection) module gates (o,i0,i1,i2,i3); output o; input i0,i1,i2,i3; wire s1, s2; and a0 (s1, i0, i1); and a1 (s2, i2, i3); and a2 (o, s1, s2); endmodule
Structural description example (explicit connection) module gates (o,i0,i1,i2,i3); output o; input i0,i1,i2,i3; wire s1, s2; and a0 ( .o (s1), .i1 (i0), .i2 (i1) ); and a1 ( .o (s2), .i1 (i2), .i2 (i3) and a2 ( .o (o), .i1 (s1), .i2 (s2) endmodule
Verilog operators Arithmetic Bitwise Relational +, - , *, Synthesizable /, % Non-synthesizable Bitwise & AND | OR ~ NOT ^ XOR ~^ XNOR Relational =, <, >, <=, >=
User-Defined Primitives Truth Table Models primitive my_UDP (y, x1, x2, x3); output y; //the output of a primitive cannot be a vector!! input x1, x2, x3; table //x1 x2 x3 : y 0 0 0 : 0; 0 0 1 : 1; 0 1 0 : 0; 0 1 1 : 0; 1 0 0 : 1; 1 0 1 : 0; 1 1 0 : 1; 1 1 1 : 0; endtable endprimitive
Truth tables with don’t cares table //? Represents a don’t care condition // on the input //i1 i2 i3 : y 0 0 0 : 0 0 0 1 : 1 0 1 0 : 0 0 1 1 : 0 1 ? ? : 1 endtable
variable assignment variable_name = value; //blocking assignment variable_name <= value; //non-blocking assignment Examples output a; output [6:0] b; reg [3:0] c; wire [2:0] d; Correct Incorrect a = 1; a <= 3; b <= 7’b0101001; b = 9’b000011011; b[1] = 0; c <= 0; d <= 0; d <= {b , c}; b <= {c, d}; b[5:2] <= c;
Propagation delay Used to assign variables or primitives with delay, modeling circuit behaviour # 5 and (s, i0, i1); -- 5 ns and gate delay #5 assign s = i0 & i1; -- 5 ns and gate delay #1 assign a = b; --1 ns wire delay Not synthesizable, is ignored by synthesis tools Useful in testbenches for creating input signal waveforms always #20 clk = ~clk -- 40 ns clock period #0 rst_n = 0; #10 rst_n = 1;
Concurrent statements –delta time b = ~ a; (a = 1, b = 1, c =0) c = a ^ b; Time a b c 0 1 1 0 δ 1 0 0 2δ 1 0 1
Continuous assignment Multiple driver error assign c = a & b; …. assign c = d | e;
Combinational circuit description module gates (d, a, c); output d; input a, c; wire d; //wire b; assign d = c ^ (~a); // assign b = ~a; // assign d = c ^ b; endmodule
Arithmetic unit description (full-adder) module add1 (cout, sum, a, b, cin); input a, b; input cin; output sum; output cout; wire cout; wire sum; assign {cout,sum} = a + b + cin; endmodule
Example Describe a 5-bit multiplier in Verilog.
Conditional assignment - describing MUXs assign = select_signal ? assignment1 : assignment1 module mux (o, s, i0, i1); output o; input i0, i1; input s; wire o; assign o = s ? i1 : i0; //if s =1 then o = i1, else o =i0 endmodule
TESTBENCH `timescale 1ns / 100ps module testbench_name (); reg ….; //declaration of register variables for DUT inputs wire …; //declaration of wires for DUT outputs DUT_name(DUT ports); initial $monitor(); //signals to be monitored (optional) initial begin #100 $finish; //end simulation end initial begin clk = 1’b0; //initialize clk #10 a = 0; #10 a = 1; … always # 50 clk = ~clk; //50 ns clk period (if there is a clock) endmodule
TESTBENCH EXAMPLE `timescale 1ns / 100ps module mux_tb (); reg i0, i1, s; wire o; mux M1 (o, s, i0, i1); initial begin #100 $finish; //end simulation end initial begin //stimulus pattern #10 i0 = 0; i1=0; s=0; #10 i0=1; #10 i0 = 0; i1=1; #10 i0=0; i1= 0; s=1; end endmodule