| Visualize 
      the Hardware: | Describe 
      the Hardware: | Comments: | 
  
    | “Do 
      Nothing” circuit | module 
      Gadget; endmodule | A 
      minimal Verilog description. The system has no I/O connections or internal 
      functionality.
 Verilog is case-sensitive throughout. Keywords must 
      appear in lower case.
 | 
  
    | “Do 
      Nothing” with I/O | module 
      Gadget (a,b,c);
 
 
 // Port modes
 input a,b;
 output 
c;
 endmodule | I/O 
      port names
 Valid Verilog names include alphanumerics, underscore 
      ‘_’, and dollar sign ‘$. Verilog names can be quite long.
 
 Describe 
      the “mode” (input or output) of each port.
 
 Has no internal 
      functionality.
 | 
  
    | Two-input 
      NAND gate based on assign 
      keyword | module 
      Gadget (a,b,c);
 /* Port modes */
 input a,b;
 output c;
 
 // Functionality
 assign c = ~(a & 
      b);
 endmodule | 
 Alternative 
      comment style
 
 
 
 Describe a NAND gate using two “bitwise” 
      operators.
 
 NOTE: The “assign” technique is called a “continuous 
      assignment.”
 | 
  
    |   | Bitwise 
      Operators:~     
      NOT
 &     
      AND
 |     
      OR
 ^     
      EXOR
 | Bitwise 
      operators work on a bit-by-bit basis; for example:
 “1 & 1” is 
      1
 “01 | 10” is 11 (binary)
 | 
  
    | Two-Input 
      NAND gate based on always 
      keyword | module 
      Gadget (a,b,c);
 // Port modes
 input a,b;
 output c;
 
 // Registered identifiers
 reg 
      c;
 
 
 
 
 
 
 
 // Functionality
 always @ (a or b)
 c <= ~(a 
      & b);
 endmodule | 
 
 
 
 
 “Registered 
      identifiers” can generate a 
      logic value. The concept of a registered identifier is broader than simply 
      an array of flip-flops; combinational circuit outputs must also be 
      declared as registered identifiers when the “always” method (“procedural 
      assignment”) is used.
 
 
 Describes a combinational circuit using 
      the procedural assignment technique. The “always” keyword means the 
      circuit always (continuously) watches the signals in the input list ( the 
      “@ (a or b)” part) and responds to changes in those signals by immediately 
      updating the output identifier.
 
 Use the “<=” symbol to assign an 
      output inside an “always” block.
 | 
  
    | Two-input 
      NAND and EXOR | module 
      Gadget (a,b,c,d);
 // Port modes
 input a,b;
 output c;
 output d;
 
 // Registered 
      identifiers
 reg c,d;
 
 // Functionality
 always @ (a or b) begin
 c <= ~(a 
      & b);
 d <= a ^ b;
 end
 endmodule | 
 
 
 Can 
      have multiple “input” and “output” declarations
 
 
 
 
 
 Can 
      enclose multiple output signal assignments inside a “begin” - “end” block; 
      everything between “begin” and “end” is treated as a single 
      statement.
 | 
  
    | Two-input 
      MUX | module 
      Mux2 (A,    // A input
 B,    // B input
 Sel,  // Selector
 Y     // 
      Output
 );
 
 // Port modes
 input A,B,Sel;
 output Y;
 
 // Registered 
      identifiers
 reg Y;
 
 // 
      Functionality
 always @ (A or 
      B or Sel)
 if (Sel==0)
 Y <= A;
 else
 Y <= B;
 endmodule | Demonstrates 
      ability to embed comments inside the code
 
 
 
 
 
 
 
 
 
 
 
 
 
 Use “if-else” 
      technique to connect output “Y” to one of the two data inputs based on the 
      value of the data selector “Sel”.
 
 The expression inside the 
      parentheses after “if” must evaluate to either “1” (true) or “0” 
      (false).
 | 
  
    |   | Relational 
      Operators:==    
      Equal to
 !=    
      Not equal
 <     Less 
      than
 >     
      Greater than
 <=    Less than or 
      equal
 >=    
      Greater than or equal
 &&    AND
 ||    
    OR
 | Relational 
      operators evaluate the comparison and return either true (1) or false 
      (0):
 In the previous example, “Sel==0” evaluates to “1” if “Sel” is 
      zero, otherwise the comparison evaluates to 
  “0”.
 | 
  
    |   | More 
      Operators:>>    
      Shift right
 <<    Shift left
 +     Add
 -     
      Subtract
 *     
      Multiply
 /     Divide
 %     
      Modulus
 | 
 
 
 
 NOTE: 
      Multiplication and division are not supported by standard hardware 
      synthesis tools
 | 
  
    | Two-input 
      MUX: Alternative method | // 
      Functionalityalways @ (A or 
      B or Sel)
 if (Sel)
 Y <= B;
 else
 Y <= A;
   | Since 
      “Sel” is a single-bit control signal, the expression inside the “(...)” 
      test can be written more concisely. | 
  
    | Two-input 
      MUX: Another alternative method | // 
      Functionalityalways @ (A or 
      B or Sel)
 Y <= (Sel) ? B : 
      A;
 | Here 
      the ternary (three-part) operator is used. The “if-else” test is embedded 
      into the assignment. Read the statement like this: “Is the control signal 
      ‘Sel’ equal to 1? If yes, then use ‘B’ when making the assignment to ‘Y’, 
      otherwise use ‘A’ ”. | 
  
    | Four-input 
      MUX | module 
      Mux4 (Data, // Data input
 Sel,  // Selector
 Y     // 
      Output
 );
 
 // Port modes
 input [3:0] Data;
 input [1:0] Sel;
 output Y;
 
 // Registered 
      identifiers
 reg Y;
 
 // 
      Functionality
 always @ (Data 
      or Sel)
 if (Sel == 0)
 Y <= Data[0];
 else if (Sel == 1)
 Y <= Data[1];
 else if (Sel == 2)
 Y <= Data[2];
 else Y <= Data[3];
 
 
 endmodule | Bus 
      widths are not included in the 
      port list.
 
 
 
 
 
 A four-bit bus. The square brackets 
      define the bus width. The left-side number is the MSB.
 
 A two-bit 
      bus is used for the data selector.
 
 
 
 
 
 “if-else-if” 
      technique
 
 
 Method for referring to individual bus 
      signals
 | 
  
    | Four-Input 
      MUX: Alternative method | // 
      Functionalityalways @ (Data 
      or Sel)
 case (Sel)
 0: Y <= Data[0];
 1: Y <= Data[1];
 2: Y <= Data[2];
 3: Y <= Data[3];
 default: Y <= Data[0];
 endcase
 | 
 “case” 
      technique (similar to “switch” statement in C language). First match 
      between the case labels (left of colon) and the signal inside the 
      parentheses causes the associated assignment to be made.
 
 “default” 
      keyword is a catch-all – if a match is not found, the default assignment 
      is made.
 
 Use “begin-end” blocks to do multiple assignments for a 
      given case selector statement.
 | 
  
    | 16-Input 
      MUX with custom behavior | module 
      Mux16 (Data, // Data input
 Sel,  // Selector
 Y     // 
      Output
 );
 
 // Port modes
 input [15:0] Data;
 input [3:0] Sel;
 output Y;
 
 // Registered 
      identifiers
 reg Y;
 
 // 
      Functionality
 always @ (Data 
      or Sel)
 casez 
      (Sel)
 4’b0000: Y <= 
      Data[0];
 4’b0001: Y <= 
      Data[1];
 
 
 
 
 
 
 4’b01??: Y <= 
      Data[2];
 
 
 
 
 
 default: Y <= Data[3];
 endcase
 
 endmodule
 | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Fully-specified 
      constant – the “4” numerical value says the constant is 4 bits wide, and 
      the ‘b says the digits are expressed in binary (use ‘d for decimal, ‘h for 
      hexadecimal, and ‘o for octal). Underscores can be used to improve 
      readability of long constants: 7’b010_0010
 
 The question mark is a 
      “don’t care” when it appears inside a numerical constant. In this example, 
      the case selection ignores the two lowest bits and looks for a match on 
      the two highest bits. You need to use the ‘casez’ version of the ‘case’ 
      statement when using “don’t cares”.
 
 All other values of the “Sel” 
      control signal cause the fourth data bit to be selected.
 
 Data bits 
      15 through 4 are effectively not used in this 
      example.
 | 
  
    | Code 
      Translator (specified as a truth table) | module 
      Code_Translator (Code_In,
 Code_Out,
 );
 
 // Port modes
 input [2:0] Code_In;
 output [2:0] Code_Out;
 
 // Registered identifiers
 reg [2:0] Code_Out;
 
 // 
      Functionality
 always @ 
      (Code_In)
 case (Code_In)
 3’b000: Code_Out <= 
      3’b101;
 3’b001: Code_Out 
      <= 3’b111;
 3’b010: 
      Code_Out <= 3’b001;
 3’b011: Code_Out <= 3’b000;
 3’b100: Code_Out <= 
      3’b100;
 3’b101: Code_Out 
      <= 3’b010;
 3’b110: 
      Code_Out <= 3’b110;
 3’b111: Code_Out <= 3’b011;
 endcase
 
 endmodule
 | 
 
 
 
 
 
 
 
 
 
 
 
 
 The 
      “case” statement can be used to directly implement a truth-table 
      specification.
 
 
 
 
 
 
 The “default” keyword is 
      optional – however, you can get unexpected results if the preceding cases 
      do not cover all possible input combinations.
 | 
  
    | Miscellaneous 
      Techniques | {a,b} 
      
 {Data[13:12],a,b,Data[11:0]}
 
 
 
 16{a}
 
 
 assign 
      Y = (en) ? X : 1’bz;
 | Group 
      signals together with curly braces
 Complex grouping – in this 
      example, two signals are inserted between existing bus signals to form a 
      new bus.
 
 Replicates the single-bit signal ‘a’ into a 16-bit bus 
      (each bus bit value is the same as ‘a’).
 
 Tristate output control. 
      When the enable (‘en’) is active, the output gets the signal ‘X’, 
      otherwise the output is in high-impedance 
  state.
 | 
  
    | 4-bit 
      magnitude comparator | module 
      Compare4 (A,    // Data input 
      A
 B,    // Data 
      input B
 AltB, // A is less than 
      B
 AeqB, // A is equal to 
      B
 AgtB  // A is > than 
      B
 );
 
 // Port modes
 input [3:0] A,B;
 output AltB,AeqB,AgtB;
 
 // 
      Registered identifiers
 reg 
      AltB,AeqB,AgtB;
 
 // Functionality
 always @ (A or B) begin
 AltB <= (A < B);
 AeqB <= 
      (A == B);
 AgtB <= (A > B);
 end
 endmodule | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Since 
      the relational operator evaluates to either a “1” or a “0”, the result of 
      the comparison can be directly assigned to the single-bit 
      result.
 | 
  
    | Parameterized 
      design for n-bit comparator | module 
      Compare4 (A,    // Data input 
      A
 B,    // Data 
      input B
 AltB, // A is less than 
      B
 AeqB, // A is equal to 
      B
 AgtB  // A is > than 
      B
 );
 
 // Define bus width
 parameter BusWidth = 
      8;
 
 // Port modes
 input [BusWidth-1:0] 
      A,B;
 output 
      AltB,AeqB,AgtB;
 // 
      Registered identifiersreg 
      AltB,AeqB,AgtB;
 
 // Functionality
 always @ (A or B) begin
 AltB <= (A < B);
 AeqB <= 
      (A == B);
 AgtB <= (A > B);
 end
 endmodule | 
 
 
 
 
 
 
 
 Define 
      bus width (use “8” in this example).
 
 
 Make all subsequent 
      references to bus width using the parameter. This way entire design can be 
      adjusted simply by changing the original parameter 
      statement.
 | 
  
    | Parameterized 
      design (alternative method) | `define 
      BusWidth 
      = 8; | This 
      technique uses a the “define” compiler directive. All compiler directives 
      begin with the backwards apostrophe. The advantage of this method over the 
      “parameter” method is that CAD tools will allow you to specify the value 
      of your “define” directive outside your Verilog modules, obviating the 
      need to edit the Verilog files themselves. This is particularly valuable 
      if you want to deliver parameterizable designs to another designer without 
      that designer having to edit the 
files. |