Verilog Rules and Examples

I. Literals

Verilog allows different ways to represent the same value in different bases.

Syntax:
<size>'<base><number>

Example:


8'b10101111   // binary representation
8'hAF         // hexadecimal representation
{4'hA, 4'b1111}   // combination of hex and binary
{4'hA, {4{1'b1}}} // hex with repeated bits
    

II. Module Declaration

Each module should be placed in a separate file named after the module.

Example:


module module_name (A, B, C);
  input A;      // Input A
  input [2:0] B; // Input B is a 3-bit signal
  output C;    // Output C
endmodule
    

III. Module Instantiation

Modules can be instantiated in other modules by mapping inputs and outputs.

Example:


module outer_module (in1, in2, out);
  input in1;
  input [2:0] in2;
  output out;

  module_name md (.A(in1), .B(in2), .C(out)); // Port mapping
endmodule
    

IV. Wire vs Reg

Wire: Used in continuous assignments.
Reg: Used in procedural assignments.

Example:


wire result;
assign result = s ? A : B;   // LHS of continuous assignment is wire

reg result;
always @(s or A or B) begin  // LHS of procedural assign is reg
  result = (s) ? A : B;
end
    

V. Sequential Logic

To create flip-flops, instantiate the provided dff module.

Example:


dff d0 (.q(flop_out), .d(flop_in), .rst(reset), .clk(clock));
    

VI. Combinational Logic

You can use assign for combinational logic or a case statement for conditional assignments.

Example:


assign result = s ? A : B;   // Continuous assign, result must be wire

reg result;
always @(s or A or B) begin  // Procedural assign, result must be reg
  casex(s)
    1'b1: result = A;
    1'b0: result = B;
    default: result = 1'bx;
  endcase
end
    

VII. Parameterized Modules

Modules can be parameterized with default values, and those parameters can be overridden when instantiating.

Example:


module register #(parameter WIDTH = 1) (output [WIDTH-1:0] out, input [WIDTH-1:0] in);
  // Register logic
endmodule

register #(32) r0 (.out(output_signal), .in(input_signal)); // Override parameter
    

VIII. Array Instantiation

Instantiate multiple instances of a module as an array.

Example:


dff_en bits[WIDTH-1:0] (.q(out), .d(in), .en(wr_en), .clk(clk), .rst(rst));
    

IX. Define Macros

Place defines in a separate configuration file and include them.

Example:


`define WIDTH 4
module modname;
  wire [`WIDTH-1:0] carry;
endmodule
    

X. Allowed Keywords

Some keywords are freely allowed: assign, module, endmodule, input, output, wire, parameter.

Example:


module foo(input A, output B);
  wire C;
  assign B = A & C;
endmodule
    

XI. Keywords with Stipulations

case, casex: Must cover all possible combinations.
always, begin, end: Use only for conditional logic.

Example:


always @(A or B) begin
  case (A)
    1'b0: B = 0;
    1'b1: B = 1;
    default: B = 1'bx;
  endcase
end
    

XII. Allowed Operators

You can use bitwise and logical operators, but shifts require constants as the second argument.

Example:


wire [7:0] result;
assign result = data << 4;  // Shift left by a constant
    

XIII. Testing Your Design

Testbenches are necessary for verification.

Example:


module foo_hier_bench;
  foo_hier f0 (.in(in), .out(out));
endmodule
    

XIV. Scripts

Use provided scripts to verify compliance with coding standards and run simulations.

XV. Submission Rules

Follow the exact guidelines for submission to avoid penalties, including directory structure and naming conventions.