Verilog Overview

Created: Mar 2004, Updated: Apr 2006

This overview is intentionally not comprehensive... far from it. I am just covering a couple of the basic forms of Verilog that are used in hardware design. I will also compare Verilog to software languages like C++ and Java with which you should be familiar.

The sections inside are:

  1. Introduction
  2. Modules
  3. Structural Descriptions
  4. Boolean Equations
  5. Hierarchical Designs
  6. Sequential Elements
  7. Finite State Machines
  8. More Reading

enjoy... yow, bill


1. Introduction

Some Verilog basics:

  • Verilog is a Hardware Description Language (that's HDL, if you want to be cool)
  • It's case-sensitive
  • It can be used to describe hardware designs at many different levels: basic behavior, FSM's, RTL's, Boolean equations, logic diagrams, etc.
  • Comment characters are // and /* ... */ ala C++
  • Statements are terminated with a semicolon.
  • Lists are usually comma-separated.
  • Verilog descriptions can be simulated
  • Some types of Verilog descriptions can also be compiled or synthesized... for example, a gate-level logic diagram may be generated from a set of Boolean equations by a software program.
  • Some important Verilog keywords are: module, endmodule, input, output, wire, and, or, not, nand, not, xor

 

 

 

 

2. Modules

Modules are the basic building blocks of Verilog. Every design or design part is a module.

Modules are like functions or methods in that they have parameters. These are the inputs to the module. Instead of a return value, modules have output parameters that are defined is a fashion similar to input parameters.

Modules can use other modules. This is like creating your own functions and calling them in C++. In hardware design, this is called "design hierarchy."

A module looks like this:

module <module_name> ( <parameter_list> );
   input <parameter_name>;
   output <parameter_name>;
   /* module body */
endmodule

Hopefully, <module_name> and <parameter_name> tokens are self-evident. The <parameter_list> is a comma-separated list of all the parameters to a module. Order is important.

Here's an example of a module name foo with two input parameters (a and b) and two output parameters (x and y):

module foo ( a, b, x, y);
   input a;
   input b;
   output x, y;   // 2 output params
 
   /* body of foo */
 
endmodule

Module parameters may be multiple bits wide. Here's an example:

module goo ( z1, z2);
   input [0:7] z1;   // 8 bits wide, 0 thru 7
   output [1:0] z2;   // 2 bits wide, 1 thru 0
 
   /* body of goo */
 
endmodule

3. Structural Descriptions

Verilog can be used to represent logic diagrams or gate-level hardware descriptions.

The wire keyword is used to represent connections between gates.

Verilog also provides keywords for the basic logic gates: and, or, not, nand, nor, xor, xnor.

Here's a very simple example AND8: an 8-bit and gate built using 2-bit and primitives:

// An 8 input and gate
module and8 ( a0, a1, a2, a3, a4, a5, a6, a7, y);
   input a0, a1, a2, a3, a4, a5, a6, a7;
   output y;
 
   wire temp1, temp2, temp3, temp4, temp5, temp6;
   and gate1( temp1, a0, a1);
   and gate2( temp2, a2, a3);
   and gate3( temp3, a4, a5);
   and gate4( temp4, a6, a7);
   and gate5( temp5, temp1, temp2);
   and gate6( temp6, temp3, temp4);
   and gate7( y, temp5, temp6);
endmodule

There are also a couple of nice examples in our text: Figure 4-32 on page 185 and Figure 4-33 on page 187.

 

 

 

 

 

 

 

 

4. Boolean Equations

The format for Boolean equations in Verilog is a little different to what we're accustomed to. The Boolean operators defined in the language are:

Verilog Symbol Boolean operator
~ not
& and
| or
^ xor

 The keyword assign is used to set the value of outputs or wires. Parentheses can be used to correctly order Boolean operators to fashion the function you are trying to express.

Here's an example my_function with 3 inputs and 2 outputs, defined using Boolean operators:

module my_function(a, b, c, f, g);
   input a, b, c;
   output f, g;
 
   wire temp;
   assign temp = ~( a & b);   // a nand b
   assign f = c | temp;   // c or temp
   assign g = c ^ temp;   // c xor temp
endmodule

 

 

 

 

 

 

 

 

 

 

5. Hierarchical Designs

Design hierarchy is created when one module uses (or calls) another. This is done in the same fashion as using the primitive gates (and, or, etc) that Verilog provides as described above in the "Structural Descriptions" section.

Here's a nice example from page 233 of our text. It's a four bit adder build out of a full adder that is in turn built out of a half adder. So, there are 3 levels of hierarchy here.

module half_adder_v(x, y, s, c);
   input x, y;
   output s, c;
 
   assign s = x ^ y;
   assign c = x & y;
endmodule
 
module full_adder_v(x, y, z, s, c);
   input x, y, z;
   output s, c;
 
   wire hs, hc, tc;
   half_adder_v   HA1(x, y, hs, hc),
                  HA2(hs, z, s, tc);
   assign c = tc | hc;
endmodule
 
module adder_4_v(B, A, C0, S, C4);
   input[3:0] B, A;
   input C0;
   output[3:0] S;
   output C4;
 
   wire[3:1] C;
   full_adder_v   Bit0(B[0], A[0], C0, S[0], C[1]),
                  Bit1(B[1], A[1], C[1], S[1], C[2]),
                  Bit2(B[2], A[2], C[2], S[2], C[3]),
                  Bit3(B[3], A[3], C[3], S[3], C4);
endmodule

Also, note that different design modules may be described in different ways: as gates, as equations, as a combination, etc.

6. Sequential Elements

Sequential elements like flipflops and latches can be modeled using Verilog. As we know, moving from combinational design to sequential design entails additional complexity. The same is true with your sequential models in Verilog. We'll need to learn some new keywords:

  • reg - is like a wire, but holds a value that must be retained over time (like until the next clock pulse)
  • begin... end - these keywords surround a process; a design may have many processes running concurrently
  • always - defines the conditions or events which start a process
  • posedge, negedge - used within an always statement, this keyword allows you to trigger a process on the edge or a change in a signal value
  • if, else - Verilog supports the if-then-else control structures that we all know and love

There is a lot of nuance to sequential descriptions that goes beyond the scope of our class. To wet your beak though, here's an example of a D flipflop that is positive edge-triggered with a reset. This example is from page 294 of our text, though you'll notice that it doesn't match exactly. Figure 6-34 is wrong because it declares Q as both an output and a reg. This is fixed up below:

module dff_v(CLK, RESET, D, Q, Q_n);
   input CLK, RESET, D; 
   output Q, Q_n;
 
   reg state;
   assign Q = state;
   assign Q_n = ~ state;
   always @(posedge CLK or posedge RESET)
   begin
      if (RESET)
         state <= 0;
      else
         state <= D;
   end 
endmodule

Finally, I snuck in a new symbol, <=, in this example. There are two flavors of assignment statements within a process: blocking and non-blocking. Blocking assignments, identified with just an equals sign (=), are handled sequentially. Non-blocking assignments, the <= flavor we have above, are evaluate the right-hand side of all non-blocking assignments before changing any values. It's a subtle point that (again) is mostly beyond our scope.

7. Finite State Machines

Just as with software languages, there are a zillion ways to do finite state machines in Verilog. I'll show you one way here. It's the method presented in out text on pages 295-297. In these pages, Verilog code for the "sequence recognizer" (as shown in the state diagram of Figure 6-24(d) on page 271) of Chapter 6 is presented.

Within the module for this design, there are three processes. Let's call then "current state", "next state" and "output". Each process deals separately with the issues of "current state", "next state" and setting the output signals. Here's the setup of the module:

// Sequence Recognizer: Verilog Process Description
// (See Figure 6-24(d) for state diagram)
module seq_rec_v(CLK, RESET, X, Z);
   input CLK, RESET, X;
   output Z; 
 
   reg [1:0] state, next_state;
   parameter A=2'b00, B = 2'b01, C = 2'b10, D = 2'b11;
   reg Z;
 
   // "current state" process, defined below
 
   // "next state process, defined below
 
   // "output signal" process, defined below
 
endmodule

The current state is positive edge-triggered (on CLK)and also dependent on the RESET input. This process is similar to the one in the D flipflop above.

   // state register: implements positive edge-triggered 
   // state storage with asynchronous reset
   always @(posedge CLK or posedge RESET)
   begin
      if (RESET)
         state <= `A;
      else
         state <= next_state;
   end

The "next state" process uses the keywords case and endcase which are similar to a switch in C++. Notice that this process is activated on any change in input X or the current state.

   // next state function: implements next state as
   // function of X and state
   always @(X or state)
   begin
      case (state)
         A:    if( X) next_state <= B;
               else next_state <= A;
         B:    if( X) next_state <= C;
               else next_state <= A;
         C:    if( X) next_state <= C;
               else next_state <= D;
         D:    if( X) next_state <= B;
               else next_state <= A;
      endcase
   end

The final "output signal" process sets the value of the output signal based on the current state and the input signal X.

   // output function: implements output as 
   // function of X and state
   always @(X or state)
   begin
      case (state)
         A:    Z <= 0;
         B:    Z <= 0;
         C:    Z <= 0;
         D:    Z <= X ? 1: 0;
      endcase
   end

This is one clean, easy approach (separate processes for state, next state, and outputs) that can generally be applied to many FSM problems.

8. More Reading

I don't really have a good book to which I can refer you. Sorry. there is a lot of online material to help, however.

I'll start at Wikipedia (of course): en.wikipedia.org/wiki/Verilog

This page has a few nice starter examples. The best thing about the page is probably the links at the bottom. Yow!

A comment on a couple of those tasty links:

  • www.asic-world.com/verilog/veritut.html - has the nicest tutorial that I have found
  • Look at all those Verilog simulators... LogicSim, Verilator, etc. I don't see Verilogger on there. Gulp. We'll see.
  • I know that Wikipedia calls www.verilog.net the "premiere" list of Verilog stuff. I found it kind of clunky though, but you try it and form your own opinion.

Just FYI, some of the other really important areas of Verilog we won't cover:

  • Other ways to describe sequential designs... there are many
  • Incorporating delays and timing issues into Verilog... ay carumba!
  • Writing Verilog that can be synthesized... it's non-trivial to get good results
  • Using Verilog tools: simulator, synthesis, etc.

thanks... yow, bill