All behavioral code is written inside module and endmodule. So, whatever digital design that you intend to create, it'll go inside a module block. It may or may not have ports defined - allow signals to enter the block as input or escape the block as output.

Module

The empty module in the example below is called testbench. You can name it whatever you like, except that it should be alphanumeric, and can contain '_'.

testbench module
  
  
module testbench;

endmodule

  

Let's look at another module. It has a few signals (d, clk, rstb) declared as inputs and q declared as an output.

dff ports
  
  
module dff (input d,
                  clk,
                  rstb,
            output q);
endmodule

  

Data Types

Now that we have seen how a module looks like, let's see what can be put inside a module, by looking at the testbench module once again. There are primarily two types of datatypes in verilog :

  • reg
  • wire
A reg datatype is used to hold onto values like a variable, while a wire is just analogous to an electrical wire, that has to be driven continuously. So typically wire is used to connect between multiple modules, and other signals.

  
  
module testbench;
	
	reg d;
	reg rst_b;
	reg clk;
	
	wire q;
endmodule

  

Assignments

Verilog has three basic blocks :

always @ (condition) always executed when the condition is satisfied
initial will be executed only once, when the simulation begins
assign [LHS] = [RHS] Value of LHS will be updated whenever RHS changes

There are a few rules to keep in mind when writing Verilog:

  • reg can be assigned to only in initial and always blocks
  • wire can be assigned a value only via assign statement
  • If there are multiple statements in an initial/always block, they should be wrapped in begin .. end

  
  
module testbench;
	
	reg d;
	reg rst_b;
	reg clk;
	
	wire q;
	
	initial begin
		d = 0;
		rst_b = 0;
		clk = 0;
		
		#100 $finish;
	end
	
	always begin
		#10 clk = ~clk;
	end
endmodule

  

Note the following from the example shown above:

  • Since there are multiple lines for initial block, begin and end are used
  • Signals d, rst_b, and clk are assigned within an initial block, because they are of type reg
  • Code inside the initial block will be executed at 0ns i.e. start of simulation
  • Since there's no condition for the always block, it will run like an infinite loop in C
  • # is used to represent time delay. #10 tells the simulator to advance simulation time by 10 units.
  • clk = ~clk; will toggle the value of clock, and because #10 is put before the statement, clock will be toggled after every 10 time units.
  • $finish is the way to end a simulation. In this case, it will run for 100 time units and exit.