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.
- Verilog-95 — IEEE 1364-1995
- Verilog-2001 — IEEE 1364-2001
- Probably, still the most commonly used standard
- Addition of signed variables to Verilog-95
- Verilog-2005
- Few changes other than new math functions
- SystemVerilog-2005 — IEEE 1800-2005
- major extensions (535 pages worth)
- Incorporation of SystemC for simulation
- SystemVerilog-2009 — IEEE 1800-2008
- Merger of Verilog and SystemC
- No more extensions to Verilog
- VPI (Verilog Procedural Interface) allows call of C functions
- SystemC standard – IEEE 1666-2011
- SystemVerilog-2012 — IEEE 1800-2012
- Altera Cyclone V
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.
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