Verilog Overview Prof. MacDonald Verilog Overview C-Like Language used to describe hardware VHDL is main competitor VHDL is more rigorous and typed VHDL takes longer to write VHDL is used by 5% of USA Verilog was originally owned by Cadence Now an open language with standards Used for ASIC design and FPGA programming Verilog HDL : A Guide to Digital Design and Synthesis by Samir Palnitkar [3:] count; if (reset) count <= 4 b; module [3:] count; if (reset) count <= 4 b; module [3:] count; if (reset) count <= 4 b; module [3:] count; if (reset) count <= 4 b; module 1
[3:] count; if (reset) count <= 4 b; module [3:] count; if (reset) count <= 4 b; module [3:] count; top = (count == 4 b1111); if (reset) count <= 4 b; module [3:] count; if (reset) count <= 4 b; module Testbench Testbench any other s reset gen clock gen circuit under test (CUT) counter.v synthesizable code monitors `timescale 1ns/1ps module tb (); reg [3:] clk, reset; count; counter counter1 (.clk(clk),.reset(reset),.count(count),.top( )); initial clk = ; //clock generator initial forever #1 clk = ~clk; //clock generator initial //main stimulus block reset <= 1 b1; #5 reset <= 1 b; #1 $finish; unsynthesizable code artificial and for verification only waveform gen tb.v testbench always @(count) $display("counter value is now %x at time %t",count, $time); initial $dumpfile("verilog.dmp"); $dumpvars; module 2
Output log (verilog.log) Output Waves Compiling source file "tb.v" Compiling source file "counter.v" Highest level modules: tb counter value is now at time 5 counter value is now 1 at time 15 counter value is now 2 at time 115 counter value is now 3 at time 125 counter value is now 4 at time 135 counter value is now 5 at time 35685 counter value is now 6 at time 35695 counter value is now 7 at time 35615 counter value is now 8 at time 356115 counter value is now 9 at time 356125 counter value is now a at time 356135 counter value is now b at time 356145 counter value is now c at time 356155 counter value is now d at time 356165 counter value is now e at time 356175 counter value is now f at time 356185 counter value is now at time 356195 counter value is now 1 at time 35625 VERILOG interrupt at time 35621 C1 > simulation events (use +profile or +listcounts option to count) CPU time:.2 secs to compile +.1 secs to link + 6.1 secs in simulation End of VERILOG-XL 3.4.p1 Nov 16, 24 9:58:9 Design Abstraction Simple Design Flow (ASIC/FPGA) High Level Behavioral C or Matlab Register Transfer Level (RTL) describes logic design with C like constructs modern definition is that RTL is synthesizable Gate level (netlist) describes design as a collection of logic gates connected together product of synthesizing RTL code Transistor level (circuit design) gates (primitives) used in synthesis details are hidden under the hood from logic designers standard cell library Specification Architecture RTL Coding Simulation Synthesis Place, Route, and Timing Verilog Data Types Combinatorial logic is represented by data type must be driven by an or continuous assignment can be connected to any number of s reg can represent either combinatorial or sequential regs in verilog are not necessarily flip-flops are defined by procedural blocks (initial or always) always blocks with posedge are sequential always blocks without posedge are combinatorial Initial blocks are for verification only (testbenches) Other less common data types include time, real, integer Verilog Data Types - busses Wires and Regs can be defined as vectors reg [7:] counter; // 8 bit register of flip-flops [1:2] data_bus; // 9 bit bus Can be individually addressed assign = data_bus[9]; or as a group assign data_bus_out = data_bus; 3
Verilog Data Types - Numbers Specification by <size> <base><number> Examples: [7:] data_bus = 8 hff; // 8 bit hex number [7:] data_bus = -1; // unsized eight ones [7:] data_bus = ; // unsized eight zeros [7:] data_bus = 8 d1; // 8-bit decimal number [7:] data_bus = 8 b11_11; // 8-bit binary Arithmetic Operators - +, -, /, *, % Arithmetic operators imply ALU in synthesis Plus operator for addition + Minus operator for subtraction Multiply operator for multiplication * Division operator / (rarely used except in TBs) Modulus operator % Ensure and precision is appropriate Underscore can be used for clarity Logical Operators Logical operators take two or more boolean vars and provide a single boolean answer. If is a vector, then false if all zeros, otherwise true AND is && OR is [3:] A = 4 d3; B = 1 b; C = A && B; // C = false or zero Bitwise Operators Bitwise operators work on each bit of vector AND & OR NOT ~ Exclusive OR ^ Exclusive NOR ~^ (compare) [3:] busa; // 11 [3:] busb; // 11 [3:] busaandb = busa & busb; // 1 Relational Operators In synthesis, relational operators imply comparison logic Compare two values and provide a boolean answer Equality == Greater than or Equal >= Greater than > Not equal!= Less than < Less than or equal to <= [7:] E = 8 d1111_111; [7:] F = 8 h1_11; assign A = (E == F); // A = assign B = (E!= F); // B = 1 Unary Operators Unary operators act on one variable Not inverts boolean AND provides the logical AND of entire bus OR provides the logical OR of entire bus XOR provides the exclusive OR of entire bus A; B; C; [7:] D = 8 b_1; [7:] E = 8 d1111_111; [7:] F = 8 h1_11; assign A = D; // A checks for 1s in D assign B = &E; // B checks for s in E assign C = ^F; // C is the parity of F 4
Shift Operators Shift <<, >> shifts the index of a bus <vector> >> <number of bits> [3:] bus = 4 ha; [3:] shifted_bus = bus >> 1; // result is 4 b11 or 4 h5 Alternative approach is using concatenation [3:] bus = 4 ha; [3:] shifted_bus = {1 b, bus[3:1]}; // result is 4 b11 Concatenation Operator Concatenation Operator {} Used to splice busses together [3:] A = 4 ha; [3:] B = 4 h5; [7:] C; assign C = {A, B}; // 8 ha5 OR assign C = {1 b, A, B[3:1]} // for shift with zero insert Codition Operator (Mux) Condition operator used to imply muxes assign <variable>= <select>? <option1> : <option>; Continuous Assignment Statements Assignment statements assign values to s and can be used to describe combinatorial circuits only. Any change on the right side, effects left side immediately if no delay is specified. Delay if specified is un-synthesizable and is for tb only. A = B? C : D; // A = C if B=1 else A = D This construct is dense and can be confusing if over-used. Ex. C; assign #2 C = (A &!B) (!A & B); Procedural Blocks Procedural blocks are used to define reg data types and can be used to describe combinatorial or sequential circuits. Procedural blocks can use C-like constructs and with always or initial key words. Each procedural block is an like an indepent thread all running in parallel. reg Q; always @(posedge CLK) if (reset) Q <= ; else Q <= D; CLK D Q Blocking vs. Non-blocking assignment Regs is procedural blocks can be defined with blocking or nonblocking assignment. Use non-blocking for flops and blocking for combinatorial. always @(posedge CLK) if (reset) Q <= ; else Q <= D; always @(A or B or Sel) if (Sel) Z = A; else Z = B; Very common interview question 5
Blocking vs. Non-blocking assignment Problem is that a race condition can exist when defining more than one flip-flop with one always block using blocking assignments. always @(posedge CLK) B = A; C = B; Other solution is to only define one reg in one always procedural block. Less confusing also. 1-> -> 1-> ->1 A B C Verilog Procedural Constructs If-then-else statement case statement for loop (not used often in synthesizable code) while loop (not used often in synthesizable code) System Calls $display dumps variable or string to standard $time tells current simulation time $stop finishes the simulation $dumpvar creates a waveform file for subsequent viewing clk1 State Machine Design Example Alternative Style (moore) x z s s2 X = 1 1 1 1 1 1 1 Z = 1 1 1 1 1 1 s1 1 Module detector (clk, reset, in, detect) clk, reset, in; detect; reg [1:] state; detect = (state == 3); if (reset) state <=; case(in or state) 2 b : if (X) state <= 1; else state <= ; 2 b1 : if (X) state <= 1; else state <= 2; 2 b1 : if (X) state <= 3; else state <= ; 2 b11 : if (X) state <= 1; else state <= 2; case module // Alternative Style (mealy) Test bench Module detector (clk, reset, in, detect) clk, reset, in; detect; reg [1:] state; detect = (state == 2) & in; if (reset) state <=; case(in or state) 2 b : if (X) state <= 1; else state <= ; 2 b1 : if (X) state <= 1; else state <= 2; 2 b1 : if (X) state <= 1; else state <= ; case module // stimulus test_bench sequence generator clock generator reset generator state_machine x clk z circuit under test checker optional Only state_machine is synthesizable. All else is for verification purposes only. 6
Testbench example - psuedocode module test_bench ( ); reg x, clk, reset; // reg declarations initial clk = ; always forever #1 clk = ~clk; // clk generation initial // sequence generation reset = 1; x = ; #(8) reset = ; @(negedge clk) x = ; @(negedge clk) x = 1; @(negedge clk) x = ; state_machine U (.in(x),.clk(clk),.detect( ),.reset(reset)); module Testbench Tasks Task adc_transaction ( ); [7:] sample; @(posedge convert) serial_data <= ; @(negedge sclk) serial_data <= sample[7]; @(negedge sclk) serial_data <= sample[6]; @(negedge sclk) serial_data <= sample[5]; @(negedge sclk) serial_data <= sample[4]; @(negedge sclk) serial_data <= sample[3]; @(negedge sclk) serial_data <= sample[2]; @(negedge sclk) serial_data <= sample[1]; @(negedge sclk) serial_data <= sample[]; $display( just transferred %x from ADC,); task Testbench monitors for the log file always @(posedge tb.dut.data_signal) $display( %d, %x, %x, %t, tb.dut.count, tb.dut.var1, tb.dut.var2, tb.dut.var3, $time); These statements provide crucial information about the sim without having to check the waveforms. Hierarchy Example (contrived) module top (clk, reset, in1, out1, out2) // should be name of file top.v clk, reset, in1; // all ports as s defined out1, out2; // all ports as s defined reg out1; // s can redefine as reg reg [1:] count; // this is an internal reg out2; // s can redefined as [1:] new_count = 2 b1; // this in an internal if(reset) out1 <= ; else if (new_count == 2 b1) out1 <= in1 && out2; else out1 <= out1; count <= count + 1; assign out2 = in1 && out1; bottom bottom1 (.ina(new_count),.outb(count)); //instantiation module Hierarchy Example (contrived page 2) module bottom (ina, outb) // should be name of file bottom.v [1:] ina; // all ports as s defined [1:] outb; // all ports as s defined [1:] outb; // s can be defined as assign outb = ina + 2 b1; // could be combined with above module Continuous statements always result in combinatorial logic - no flops or latches. start; assign start = ready && request; 7
Continuous statements always result in combinatorial logic. Here is a 32 bit comparator. Note that the size of the netlist doesn t necessarily correspond to the number of lines of RTL Wire [31:] a ; Wire [31:] b ; Wire the_same ; Always block without posedge statement is combinatorial. Always @(D or S or E) else A = E; Always @(*) // verilog 2 else A = E; Assign the_same = (a == b); Always block without posedge statement is combinatorial. This example will result in an ALU function (potentially very large). Wire [31:] ina; Wire [31:] inb; Reg [31:] out; always @(ina or inb or subract) if (subtract) out = ina + (!inb + 32 h1); else out = ina + inb; Always block without posedge statement is combinatorial. This example will result in decoder (8 3- AND gates). always @(index) case (index) : decoder_out = 8 h1; 1: decoder_out = 8 h2; 2: decoder_out = 8 h4; 3: decoder_out = 8 h8; 4: decoder_out = 8 h1; 5: decoder_out = 8 h2; 6: decoder_out = 8 h4; 7: decoder_out = 8 h8; case Always block without posedge statement is combinatorial. This example will has a problem. All cases must be specified. Here if enable is high, Q=D. What happens if enable is low? Synthesis will add a latch to remember the old value of Q when it is undefined by the if statement. Latches are rarely meant to be used in logic and are a good sign of a problem. Always block with posedge clk statement is sequential. This example will result in a simple non-resetable flip-flop. Flip flops that define state or control should be reset, however flip flops in the datapath can be left un-reset if data naturally flows through to initialize. always @(*) if (enable) Q = D; Very common interview question A <= E; 8
Always block with posedge clk statement is sequential. This example will result in a synchronous resetable flip-flop. The reset requires the clock edge to take effect. Always block with posedge clk statement is sequential. This example will result in a asynchronously resettable flip-flop. The reset will take effect immediately without requiring a clock. if (!resetn) A <= ; else A <= E; resetn A clk The decision between asynch and synch reseting is controversial. Potential interview question. always @(posedge clk or negedge reset) if (!resetn) A <= ; else A <= E; A clk resetn Asynch vs Synch Reset Advantages and disadvantages to both styles: Asynch flip-flops do not require the clock and thus avoid problems at power up where Vdd is available but not yet a clock. Logic and IO are therefore forced into a known state immediately avoiding shorts with tristatable logic and other problems. The problem with asynch flip-flops is that any glitch from noise on the signal will result in an inadvertent reset of the state as they are edge-triggered. Synch flip-flops are only sampled on the clock edge and with proper timing will never see a glitch and are therefore considered more robust. Potential interview question. resetn A clk clk A resetn Always block with posedge clk statement is sequential but can include some combinatorial logic as shown. if (reset) A <= ; else A <= E && C; E C clk Hold Time Violation Review Shift register for parallel to serial conversion susceptible to hold time violations module p2s (in, out, load, clk, reset) load, clk, reset; [7:] in; out; reg [7:] parallel_data; out = parallel_data[7]; if (reset) parallel_data <= ; else if (load) parallel_data <= in; else parallel_data <= {parallel[6:], 1 b}; module d1 = 1 clk1 clock tree d2 clk2 d3 Caused by clock skew Sinister problem Cannot fix with frequency Clock synthesis and balancing very important Good case: No clock skew d2 1 -> d3 -> 1 Bad case: 12ns clock skew d2 1 -> d3 -> 9
- Latches Examples rolling average Always block with posedge clk statement is sequential. This example will result in a transparent latch. Very unusual in RTL. Typically, latches in the synthesized netlist are the sign of mistakes. always @(clk or in) //unusual but intentional latch if (clk) A = in; else A = A; always @(*) // typical unintentional latch if (enable) A = in; average <= average[15:] + {{8{data_[15]}}, data_[15:8]} {{8{average[15]}}, average[15:8]}; average = average + (1/256) * data_ (1/256) * average Handles signed s always @(*) // intentional combinatorial mux if (enable) A = in1; else A = in2 Examples parallel to serial Examples signed multiplier [7:] reg [7:] parallel_; serial_; parallel_reg; if(reset) parallel_reg <= ; else if (shift_left_enable) parallel_reg <= {parallel [6:], serial_}; else if (shift_right_enable) parallel_reg <= {serial_, parallel [7:1]}; else if (load_enable) parallel_reg <= parallel_; else parallel_reg <= parallel_reg; reg [15:] product; [7:] an = a[7]? (~a + 1) : a; [7:] bn = b[7]? (~b + 1) : b; always @(a or b or an or bn) if(~b[7] && ~a[7]) product = a * b; else if (a[7] && ~b[7]) product = an * b; else if (~a[7] && b[7]) product = a * bn; else product = an * bn; Resets to zero. Shifts to the left on every clock edge with shift_left_enable high. Shifts to the right on every clock edge with shift_right_enable high. Broad side loads with load_enable Hold value otherwise. Verilog Design Guidelines Most common student mistakes Use meaningful names for signals and variables Use I_ and O_ for port names I for / O for Modify regs in only one always block Constants and Parameters should be all caps Never use tabs but do line up text with spaces Avoid mixing positive and negative edge-triggered flip-flops Use parentheses to optimize logic structure Use continuous assign statements for simple combo logic. Use non-blocking for sequential and blocking for combo logic Define if-else/case statements explicitly all vars for all cases Always instantiate modules with explicit port listing. Synthesizable code should not have delays included (#) only have always blocks and no initial blocks Define a reg in only one always block (otherwise ambiguity) for loops are for spatial repeating - not temporal Fully specify variables within an always block for readability i.e. if (X) Y = A, else Y = B. Define Y in all possible cases. this may result in unwanted latches (as opposed to flip-flops) Fully specify sensitivity list in combinatorial always blocks Blocking vs. Non-blocking assignments rule of thumb if it has a posedge, use the <= because it is sequential otherwise use the = because it is combinational Really doesn t matter if you only define a single variable in a block 1
Examples of bad code In any always block, define all variables for all cases. Not doing so can cause latches and in general is hard to follow. Furthermore, should have one always block per reg for clarity. always @(C or D or S or E) if (S) A = D; B = C; else A = E; BAD always @(C or D or S or E or F) if (S) A = D; B = C; else A = E; B = F; BETTER always @(D or S or E) else A = E; always @(C or S or E) if (S) B = C; else B = F; BEST Examples of bad code Define any variable in only one always block. Otherwise, simulation and synthesis will mismatch. always @(D or S) always @(G or E) if (G) A = E; always @(D or E or G or S) else if (G) A = E; else A = K; Examples of bad code Reference Define only one if-else statement per always block. Define only one reg per always block. Better to have one block for each variable and one variable per block. always @(D or S or K or J or E or C or G ) else if A = J; else A = K; if (G) B <= E; else B <= C; always @(D or E or G or S) else if A = J; else A = K; always @(G or E or C) if (G) B = E; else B = C; Verilog 21 Standard new features added port list and / declarations combined sensitivity lists in always blocks need not be listed Good reference web pages for Verilog www.deepchip.com opencores.com www.edacafe.com www.cadence.com original company www.synopsys.com most used synthesis tool www.mentor.com commonly used simulator www.magma-da.com new synthesis tool www.altera.com FPGA company www.xylinx.com FPGA company 11