All behavioral code is written inside module and endmodule. It may or may not have ports defined to 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

Th module shown below 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

There are primarily two main datatypes in Verilog used for hardware synthesis, reg and 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
initialwill 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.