Structural Verilog specifications are very handy for simulation purposes, especially when verification of a large scale system design is needed: you can be certain that all desired transistors are definitely where they need to be if your layout passes LVS, and your Verilog passes your tests. (You could still have trouble with timing of course!)
But that same Structural Verilog code that validates every logic gate in your design probably isn’t very fit for human consumption, and you definitely don’t want to write it by hand. You want to specify as much hardware in as little HDL as possible.
Which is where Behavioral Verilog comes in. Verilog supports doing in a few lines what would take hours to hand-design in gates. For example, this behavioral code for a multiplier and an adder:
module bench; reg [3:0]A,B,C,D; wire [3:0]X; wire [7:0]Y; assign X=A+B; assign Y=C*D; initial begin $dumpvars(0,bench); #1; A=2; B=3; C=2; D=3; #4; A=11; B=6; C=5; D=5; #4; $finish; end endmodule
Overflows are handled gracefully and in the same way you would expect a computer to handle them, and Verilog tracks each bit of each number as its own wire. Verilog defaults to using 2’s compliment to represent negative numbers. Each assign statement represents an entire combinational math component.
What makes a file like this representative of the true power of Verilog, however, is that you can just go up to the bus widths and type in any size number you like. You could specify 1024-bit adders and 2048-bit multipliers in this same file by changing a few numbers. Behavioral Verilog descriptions may be inexact in terms of final implementation, but they specify the hardware’s total functional behavior, for every possible set of digital inputs and outputs.
A behavioral model of an adder will not tell you anything about the delays of its internal gates, but it will tell you everything about how it adds. And you can specify it in one line, no matter how big it is.