Hardware Description

Languages : VHDL and Verilog

David Nguyen, Duy-Ky Nguyen, PhD

1. Introduction

VHDL was first created by DOD contractors IBM, Texas Intruments and Intermetrics to document a large discrete digital project in 1980. Verilog was created by an engineer named Phil Moorby at a CAE company called Gateway Design Automation to verify a large discrete digital projects in 1981.

VHDL is a Pascal/Ada-like language (case insensitive) while Verilog is C-like language (case sensitive).

VHDL is more programming language than Verilog as it has many data types for signal and variable. Verilog is better to describe hardware and 2 basic data types, 1 for combinatory digital (memory-less like gate, decoder, mux, ...) and 1 for sequential digital (memory like flip-flop). It has only signal, not variable (signal is also variable, anyway).

2. Comparison

This notes presents only HDL sufficient enough for synthesis and basic simulation for verification.

2.1. Data Type

VHDL Verilog
Many data types, each for both combinatory and sequential
  • Signal (comb` and seq`)
  • Std_logic, std_logic_vector (comb` and seq`)
  • Integer (a must for RAM modeling)
Only 2 data types separately for comb` and seq`
  • wire (combinatory)
  • reg (sequential)
Logic
  • `0`, `1`, `Z` (1-bit)
  • "00010010" or x12 (8-bit)
  • "010010" or (1|4 => `1`, others => `0`) (6-bit)
  • (others => `Z`) (16-bit)
Logic
  • 1`b0, 1`b1, `1bZ (1-bit, b for binary)
  • 8`h12 (8-bit, h for hex)
  • 6`h12 (6-bit)
  • 16`bZ (16-bit)
Number 196 decimal
  • 196 (decimal)
  • 2#1000_0100# (binary)
  • 16#c4# (hex)
Number 196 decimal
  • 'd196 or simply 196 (decimal)
  • 'b1000_0100 (binary)
  • 'hc4 (hex)

Digital Hw has nothing else but 1-bit (binary digit) combinatory and sequential digital. Verilog uses only these information to create its data types while VHDL has much more data types.

Verilog has

wire		comb_sig;	// combinatory signal
reg	[7:0]	data_bus;	// sequential data bus
While
signal comb_sig : std_logic;
signal data_bus : std_logic_vector (7 downto 0);

So, Verilog is more efficient in describing digital HW in term of data type and number as it focus on

2.2. Operators

VHDL Verilog
Concatenation: & ()
  • Bit & vector
  • ( bit_2, bit_1, bit_0 ) (aggregate for bit only)
However, VHDL concatenation also requires extra signal declaration before further processing, like
signal sel_vec : std_logic_vector  (1 downto 0);
Sel_vec = (sel_bit_1, sel_bit_0);
case  sel_vec
	when "00" => . . .
	
Concatenation: { }
  • { bit, vector }
  • { bit_2, bit_1, bit_0 }
Verilog concatenation can be used directly in any procession
case  ({sel_bit_1, sel_bit_0})
	0 : . . .
	
Replication : None Replication : { { } }
{ 4 {vector } } = { vector, vector, vector, vector}
Reduction :None Reduction & | ^
	& {bit_3, bit_2, bit_1, bit_0} = bit_3 & bit_2 & bit_1 &bit_0

So, Verilog is again more efficient to describe digital HW for its clean bit and vector (multi-bit) representations while bit is the only object in digital HW, nothing else.

2.3. IO Interface

VHDL Verilog
In, out, inout
However, out cannot be read, it requires extra signal declaration in doing so
Out_sig : out std_logic;
signal out_tmp : std_logic;
Out <= out_tmp;
. . .
out_tmp <= sig_1;
sig2 <= out_tmp;
Input, output, inout
Out can be read
output	out_sig;
Out_sig <= sig1;
Sig2 <= out_sig;

For some unknown reason, VHDL has unrealistic write-only feature for OUT, while, in real digital HW, there`s read-only (ROM - Read Only Memory), but not write-only.

2.4. Function and Procedure/Task

VHDL Verilog
function name (arguments) return
	std_logic_vector  (7 downto 0) is
-- variable
Begin
-- function body
End name;
function [7:0] name;
// input only (arguments);
begin;
-- function body
end;
endfunction;
Procedure name (in-out list) is
-- variable;
begin
-- procedure body
end name;
task name;
// in/out list;
begin
-- task body
end
endtask

To return single value, both VHDL and Verilog use function. However, VHDL uses arguments as inputs like high-level programming language, but Verilog uses regular input-list.

To include timing control, VHDL uses procedure while Verilog uses task. Both use IO list.

So, once again, Verilog has more consistent approach for function, task/procedure than VHDL.

2.5. RAM Simulation Model

VHDL Verilog
type RAM is array (0 to 31)
	of std_logic_vector (7 downto 0);

begin

process (clk)
variable RAMa : RAM;

variable aa : integer := 0;
begin
aa := conv_integer(addr);
if rising_edge(clk) and en='1' then
	if (we='1') then
		RAMa(aa) := din;
	end if;
	dout <= RAMa(aa);
end if;
end process;
reg	[7:0]	RAMa [0:31;
always @ (posedge clk) begin
	if (we)
		RAMa[addr] <= din;
	dout <= RAMa[addr];
end

2.6. Brief Summary on VHDL and Verilog

VHDL (case Insensitive) Verilog (case Sensitive)
-- VHDL line comment // Verilog line comment
Block comment: None /* Block comment */
Architecture:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity name is port (
	-- IO interface and list);end name;
architecture name of name is
-- signal for both combinatory and sequential
-- component
begin -- architecture body
-- combinatory assignment
process (sensitive list)
-- sequential
-- variable
begin    -- body
end process;end name;
module name (		// like VHDL entity
	//IO interface);
// IO list (separate IO interface and list)
// No architecture section
// wire for combinatory (gate, mux, ...)
// reg for sequential (flip-flop)
// combinatory assignment
always @(sensitive list) begin -- sequential
// body, like VHDL process
end
endmodule
Vector: ()
signal a_vec: std_logic_vector (7 downto 0);
A_vec(0) for bit 0		
[]
reg [7:0] a_vec;
a_vec[0] for bit 0
Assignments: <= :=
<= for signal (both comb` and seq`)
:= for variable
X_bit <= `1`;	-- 1-bit
X_vec <= "0000" 	-- 4-bit
X_vec <= x"0"	-- hex for 4-muliple only
X_vec <= "000000"	-- 6-bit, no hex avail.
X_vec <= "ZZZZ"	-- no hex avail.
	It`s hard to type 32 Z`s for 32-bit data
= <= = for combinatory <= for sequential X_bit = 1`b1; // or x_bit = 1 X_vec = 4`b0; // or x_vec = 0 X_vec = `h0; // drop size # (4) X_vec = 6`b0 // or x_vec = 0 X_vec = `hZ; //
Gates: not and nand or nor xor xnor
X <= not a;
X <= a and (not b);
X <= not (a and b);
X <= a or b;
X <= not (a or b);
X <= a xor b;
X <= a xnor b;
~ & ~& | ~| ^ ~^
x = ~a;
x = a & (~b);
x = ~(a & b);
x = a | b;
x = ~(a | b);
x = a ^ b;
x = a ~^ b;	// x = a ^~ b;
Shift: sll srl
X <= a sll 3;
<< >>
x = a << 2;
Concat: &
X <= a_vec(5 downto 0) & a_vec(6)
{}
x = {a_vec[5:0], a_vec[6]};
Aggregate: (, )-- bit only
X <= (a_bit, b_bit)
{}
x = {a_bit, b_bit};
Replica: None
{{}}
x = {a_bit, a_bit, a_bit, b_vec, b_vec};=> x = {3{a_bit}, 2{b_vec}};
Relational: = /= < <= > >=
X <= `1` when a=b else `0`;	-- comb` only

if (a=b) then	-- seq` only
	X <= `1`;
else
	X <= `0`;
end if;
 == != < <= > >=
X = (a == b);	// both comb` and seq`
Logical: not and or
(a=b) and (c/=d)
! && ||
(a==b) && (c!=d)
Reduction: None
X <= a_vec(2) and a_vec(1) and a_vec(0)
& | ~& ~|
x = &a_vec[2:0];
Conditional: when else --For combinatory only!
X <= "00" when S="00"
else "01" when S="01"
else "10" when S="10"
else "11";
? : //For both combinatory and sequential
X = (s==0) ? 0
: (==1) ? 1
: (s==2) ? 2
: 3;
if () then
--  block statement (no begin end)
Elsif then   --
else   --
end if;
if ()   //  block statement (begin end)
else if   //
else   //
function name (arguments) return
	std_logic_vector  (7 downto 0) is
-- variable
Begin
End name;
function [7:0] name;// input only (arguments)
begin
End
endfunction
procedure name (in-out list) is
-- variable
begin
end name;
task name;// in/out list
begin
end
endtask

3. Conclusion

Programming languages, like Pascal/Ada or C, basically deals with numbers and character using computer while computers know nothing but binary digit (bit). These bits are interpreted as numbers or character depending on their usages. That's why programming langaues do require type to fulfil this task. For example, the bits 01100101 (65 decimal) is the number 65 for integer type, but character 'A' for character type. Even a number could be an integer number or a real number with decimal point. Even more, a real number could be single precision or double precision (more digits after decimal point).

However, Hardware Description langguages, like VHDL or Verilog, deals with nothing but logic bits, like 0, 1 or tristate 'Z' in digital electronics. They should also describe 2 types of digital electronics combinatrory (memoryless) and sequential (memory).

VHDL is a strong-type language with many types like programming language, probably because it was created by SW engineers, unlike Verilog created by HW engineers?

Verilog has only 2 types wire for combinatory digital and reg for sequential digital.

Verilog deals with bit and array of bits of a bus far more efficient than VHDL. Strong-type feature makes programming language more efficient, but makes VHDL very clumsy.

At some point, it's usual to deal with with bitwise like below

VHDL Verilog
ABC_A : ABC	PORT MAP(
   IN(0) => IN0,
   IN(1) => IN1,
   IN(2) => IN2,
   IN(3) => IN3,
   IN(4) => IN4,
   IN(5) => IN5,
   IN(6) => IN6,
   IN(7) => IN7,
   OUT   => X
);
ABC ABC_A (
   .IN({IN7, IN6, In5, In4, IN3, IN2, IN1, IN0}),
   .OUT(X)
);

Just imagine if we have 32 bits instead of 8 bits above, we'll see how painful in using VHDL.

In fact, there's a way to make thing easier in VHDL in dealing with this issue by using extra signal or variable as below

VHDL Verilog
. . .
signal	IN_8x: std_logic_vector(7 downto 0);
. . .
IN_8x <= (IN7, IN6, In5, In4, IN3, IN2, IN1, IN0);

ABC_A : ABC	PORT MAP(
   IN  => IN_8x,
   OUT => X
);
ABC ABC_A (
   .IN({IN7, IN6, In5, In4, IN3, IN2, IN1, IN0}),
   .OUT(X)
);

However, extra signals will make debugging more difficult.

Verilog has cleaner, more consistent and convenient constructions to represent digital HW than VHDL. These are very reasons why Verilog has some greater features below vs VHDL