Other Verilog stuff

Events in Verilog history

Before there were hardware description languages, designers used an informal notation called register transfer language or RTL. It has even been used in CSCI 255 / ECE 109 to specify the implementation of a very simple computer.

Here is a list of the Verilog standards. These are managed by Accellera System Initiative, which was formed from a merger of the Verilog, VHDL & SystemC specification groups.

Some Verilog programs

Structural implementation of a full adder

module fulladder(
   input An,          // A bit
   input Bn,          // B bit
   input Cn,          // carry-in bit
   output Cnp1,       // carry-out bit
   output Sn) ;       // sum bit

      wire tAB, tAC, tBC ;        // wires leaving the AND gates

      xor(Sn, An, Bn, Cn) ;
      and(tAB, An, Bn) ;
      and(tAC, An, Cn) ;
      and(tBC, Bn, Cn) ;
      or(Cnp1, tAB, tAB, tBC) ;

endmodule

Structural implementation of a full adder with named gates

module fulladder(
   input An,          // A bit
   input Bn,          // B bit
   input Cn,          // carry-in bit
   output Cnp1,       // carry-out bit
   output Sn) ;       // sum bit

      wire tAB, tAC, tBC ;        // wires leaving the AND gates

      xor  sum(Sn, An, Bn, Cn) ;
      and  abTerm(tAB, An, Bn) ;
      and  acTerm(tAC, An, Cn) ;
      and  bdTerm(tBC, Bn, Cn) ;
      or   carry(Cnp1, tAB, tAC, tBC) ;

endmodule

Behavioral implementation of a full adder

module fulladder(
   input An,          // A bit
   input Bn,          // B bit
   input Cn,          // carry-in bit
   output Cnp1,       // carry-out bit
   output Sn) ;       // sum bit

      assign Sn = An ^ Bn ^ Cn ;
      assign Cnp1 = An & Bn | An & Cn | Bn & Cn ;

endmodule

Behavioral implementation of a full adder using addition

module fulladder(
   input An,          // A bit
   input Bn,          // B bit
   input Cn,          // carry-in bit
   output Cnp1,       // carry-out bit
   output Sn) ;       // sum bit

     wire[1:0] sum2bit ;
     assign sum2bit = An + Bn + Cn ;
     assign Sn = sum2bit[0] ;
     assign Cnp1 = sum2bit[1] ;

endmodule

Behavioral implementation of a full adder tattoo

This tattoo is mentioned in a Discover blog.
full adder tattoo
The program is taken from the textbook.

// 4.7: fulladder

module fulladder(input  logic a, b, cin, 
                 output logic s, cout);

  logic p, g;

  assign p = a ^ b;
  assign g = a & b;
  
  assign s = p ^ cin;
  assign cout = g | (p & cin);
endmodule

Sequential circuits

Resetable flip-flop

// 4.18b: flopr_sync
// synchronously resettable flip flop

module flopr(input  logic       clk,
             input  logic       reset, 
             input  logic [3:0] d, 
             output logic [3:0] q);

  // synchronous reset
  always_ff @(posedge clk)
     if (reset) q <= 4'b0;
     else       q <= d;
endmodule

Moore FSM

// 4.31: patternMoore

module patternMoore(input  logic clk, 
                    input  logic reset, 
                    input  logic a,
                    output logic y);

  typedef enum logic [1:0] {S0, S1, S2} statetype;
  statetype state, nextstate;

  // state register
  always_ff @(posedge clk, posedge reset)
    if (reset) state <= S0;
    else       state <= nextstate;

  // next state logic
  always_comb
    case (state)
      S0: if (a) nextstate <= S0;
          else   nextstate <= S1;
      S1: if (a) nextstate <= S2;
          else   nextstate <= S1;
      S2: if (a) nextstate <= S0;
          else   nextstate <= S1;
      default:   nextstate <= S0;
    endcase

  // output logic
  assign y = (state == S2);
endmodule

Mealy FSM

// 4.32: patternMealy

module patternMealy(input  logic clk, 
                    input  logic reset, 
                    input  logic a,
                    output logic y);

  typedef enum logic {S0, S1} statetype;
  statetype state, nextstate;

  // state register
  always_ff @(posedge clk, posedge reset)
    if (reset) state <= S0;
    else       state <= nextstate;

  // next state logic
  always_comb
    case (state)
      S0: if (a) nextstate <= S0;
          else   nextstate <= S1;
      S1: if (a) nextstate <= S0;
          else   nextstate <= S1;
      default:   nextstate <= S0;
    endcase

  // output logic
  assign y = (a & state == S1);
endmodule

Testbench module

Special simulator commands, such as $display, begin with a dollar sign. These are not synthesizable.

module testbench() ;
   reg[2:0]  vin ;              // a 3-bit register
   integer i ;
 
   wire[1:0] vout ;             // a 2-bit bus

   fulladder dut(vin[2], vin[1], vin[0], vout[1], vout[0]) ;

   initial begin
      for (i=0; i<8; i=i+1)
      begin
         vin = i ; #100 ;       // wait 100 time units
         $display("vin = %h, vout = %h", vin, vout) ;
      end
   end
endmodule