Design Using HDL'S: VHDL, Verilog
Design Using HDL'S: VHDL, Verilog
VHDL, Verilog
Similarities, Differences & Good Design Practices
For ECE412 Spring 08 Alex Papakonstantinou
Background
VHDL development sponsored by the US- DoD and the IEEE in mid 80s VHDL became IEEE standard 1076 in 1987 VHDL versions: VHDL-87, VHDL-93, VHDL2001, Child standards: 1076.1 VHDL-AMS provides analog and mixed-signal extensions 1076.2 added real and complex data types 1076.3 added unsigned and signed types Verilog was launched by Gateway in 1983 which was bought by Cadence in 1989 Cadence opened Verilog to the public domain in 1990 Verilog became IEEE Standard 1364 in 1995 Verilog versions: Verilog 1995, Verilog 2001 Verilog-AMS : separate part of Verilog standard Verilog-2005 System Verilog: Superset of Verilog aiming for higher abstraction design modeling
VHDL 2006 Draft 3.0 by Accellera Both VHDL and Verilog are Industry Standards Both can be used to implement algorithms for specification simulation or synthesis purposes Both can be used for structural or behavioral design modeling
Common Characteristics
Look similar to conventional programming languages However, they have a significant difference with regards to programming languages: they are inherently Parallel Allow different levels of abstraction: Behavioral Result := a*b + c mod i Structural
mul0: MUL port map (A_op, B_op, R1) mod0: MOD port map (C_op, I_op, R2) add1: ADD port map (R1, R2, Result)
Design Components
VHDL
ENTITY mux IS PORT ( a : IN BIT; b : IN BIT; c : IN BIT; d : IN BIT; s0 : IN BIT; s1 : IN BIT; x : OUT BIT); END mux ARCHITECTURE dataflow OF mux IS ... END dataflow
Verilog
Verilog
module mux ( a, b, c, d, s0, s1, x ); parameter W = 3; input [W:0] a, b, c, d; input s0, s1; output [W:0] x; ... endmodule
Design Instantiation
VHDL
Using Positional Association
ARCHITECTURE struct OF logic IS COMPONENT and2 PORT (a, b : IN BIT; c : OUT BIT); END COMPONENT; SIGNAL a1, a2, b1, b2, c1 : BIT; BEGIN U1: and2 PORT MAP (a1, a2, b1); U2: and2 PORT MAP (b1, b2, c1); endmodule ... and2 u1 (a1, a2, b1); and2 u2 (b1, b2, c1); ...
Verilog
Using Positional Association
module logic ( ... ); input ... wire a1, a2, b1, b2, c1;
Design Instantiation
VHDL
Using Explicit Association
ARCHITECTURE struct OF logic IS COMPONENT and2 PORT (a, b : IN BIT; c : OUT BIT); END COMPONENT; SIGNAL a1, a2, b1, b2, c1 : BIT; BEGIN U1: and2 PORT MAP (a=>a1, b=> a2, c=> b1); U2: and2 PORT MAP (c=> c1, a=> b1, b=> b2); ... and2 u1 (.a(a1), .b(a2), .c(b1) ); and2 u2 (.c(c1), .a(b1), .b(b2) ); ... endmodule Sequence of instantiation does not matter!
Verilog
Using Explicit Association
module logic ( ... ); input . . . ... wire a1, a2, b1, b2, c1;
Data Types
VHDL
bit : bit_vector : boolean : character : integer : natural : positive : real* : time* : 1 1001 true a 139 0 1 -2.3 5 ns
Verilog
{0,1,x,z} 10 4.3
All the above data types are included in the standard library : library std; use std.standard.all;
*
More Types
VHDL
type STD_ULOGIC is ( U, -- uninitialized X, -- forcing unknown 0, -- forcing 0 1, -- forcing 1 Z, -- high impedance W, -- weak unknown L, -- weak 0 H. -- weak 1 -); -- dont care STD_LOGIC STD_ULOGIC_VECTOR STD_LOGIC_VECTOR
User can define similarly custom data types: TYPE small_int IS range 0 to 1024; TYPE word_len IS 31 downto 0; TYPE opcod IS (load,store,add,sub);
VHDL is strongly-typed, and thus assignments can occur only between signals of the same type. However, assignment between a type and its subtypes are allowed
Arrays
VHDL
Declaration: TYPE word IS ARRAY (15 downto 0) of std_logic; TYPE vector IS ARRAY (natural range <>) of integer; TYPE matrix3x2 IS ARRAY (1 to 3, 1 to 2) of natural; Instantiation: VARIABLE data_arr : matrix3x2 := ((0,2),(1,3),(4,6)); Array access: data_arr(3,1);;
Verilog
Data Objects
VHDL
constant (declared at the start of an architecture) signal (gets updated a delta delay after its assignment statement is executed) variable (only exist and are used in procedural blocks)
Verilog
parameter (used as a constant) wire (used in concurrent assignments)
wand (wired-AND) Wor (wired_OR) tri (tri-state) supply0 supply1
reg (used in procedural assignments, data is stored in unsigned format for multi-bits)
input, output, inout (By default are of type wire, but can be configured as any of the above types, with the exception of parameter)
Operators
VHDL
= /= < <= > >=
Verilog
== != < <= > >=
Relational Equality Inequality Less Than Less Than or Equal Greater Than Greater Than or Equal Logical/Bitwise and or not xor nand nor xnor
Operators (2)
VHDL
+ * / MOD REM
Arithmetic addition subtraction multiplication division modulus Remainder Shift shift left logical shift right logical shift left arithmetic shift right arithmetic rotate left rotate right
Verilog
+ * / % N.A.
Operators (3)
VHDL
** ABS & Arithmetic exponentiation absolute value Concatenation
& | ~& ~| ^ ~^
Verilog
Reduction reduction and reduction or reduction nand reduction or reduction xor reduction xnor Concatenation n-Replication Conditional
{} {n{ } } ?:
Concurrent Statements
VHDL
Simple Signal Assignment: sum <= (a XOR b) XOR cin; carry <= a AND b ; Conditional Signal Assignment: z <= a WHEN s1=0 AND s0=0 ELSE b WHEN s1=0 AND s0=1 ELSE c WHEN s1=1 AND s0=0 ELSE d ; Selected Signal Assignment: WITH sel SELECT z <= a WHEN 00, b WHEN 01, c WHEN 10, d WHEN 11;
Verilog
Simple Signal Assignment: assign sum = (a ^ b) ^ cin; assign carry = a & b ; Conditional Signal Assignment: assign z <= s1? (s0 ? d : c) : (s0 ? b : a);
Priority is inferred based on the order of selection values No two choices can overlap All ppossible cases must be covered if when others is not present All options have equal priority
Inferred Priority
Conditional Signal Assignment: assign z <= s1? d : (s0 ? c : (s2 ? b : a) );
Verilog
Combinational procedure:
always@(a or b or c) begin if ( c ) out <= a; else out <= b; end
Sensitivity list is usually ignored during synthesis (it must contain all read signals) Sensitivity list can be replaced by WAIT ON a,b,c at the end of process Use either WAIT ON or Sens. List, NOT both
Make sure there are no missing clauses (otherwise a latch may be inferred) Latches should be avoided in synchronous designs In Verilog 2001, sensitivity list can be replaced by star (*) which substitutes all the read signals
Verilog
Sequential procedure:
always@(posedge clk) begin if ( c ) out <= a; end
Missing clauses do not infer any latches in this case Two types of assignment:
non-blocking ( <= ) blocking (=)
Verilog
Synchronous Reset:
always@(posedge clk) begin if ( rst ) out <= 0; else out <= a; end
Asynchronous Reset
PROCESS (clk, rst) BEGIN IF (rst = 1) THEN out < 0; ELSIF (clkEVENT AND clk = 1) THEN out <= a; END IF; END PROCESS;
Asynchronous Reset
always@(posedge clk, posedge rst) begin if ( rst ) out <= 0; else out <= a; end
Verilog
Only reg objects can be assigned within procedures <= non-blocking assignments Evaluated in parallel regardless their order Should be used in sequential procedures to implement flip-flops Good to use when same variable appears in both sides of <= = blocking assignment evaluated in the order statements are written Should be used for combinational logic
:= variable assignments Evaluated in the order statements are written Good for algorithm implementation with combinational logic Variables only accessible within procedure Registers are generated for variables that might be read before being updated (since variables keep their value between process calls)!
For synthesis should not mix different types of assignments in the same procedure
if statements
VHDL
z <= a; IF (x = 1111) THEN Z <= B; ELSIF (x > 1000) THEN z <= c; END IF;
IF (x = 1111) THEN z <= b; ELSIF (x > 1000) THEN z <= c; ELSE z <= a; END IF;
Verilog
z = a; if (x = 4b1111) begin z <= b; end else if (x > 4b1000) begin z = c; end if (x = 4b1111) begin z <= b; end else if (x > 4b1000) begin z = c; end else begin z = a; end
Used only within procedures Conditions might overlap Processed sequentially and thus implies priority (statements within first true condition will be executed) Instead of an else clause a default statement may be used before if elsif statement (as shown in above example) All cases should be covered in order to avoid latch inference
case statements
VHDL
CASE x IS WHEN 0000 WHEN 0111 | 1001 WHEN OTHERS END CASE; => z <=a; => z <= b; => z <= 0;
Verilog
: z = a; : z = b; : z = 0;
Used only within procedures case options must not overlap All choice options have to be covered All branches equal in priority when others covers all remaining choice options
Used only within procedures case options can overlap All choice options should be covered to avoid latch inference Higher branches have bigger priority Special directives are supported by CAD vendors to infer equal priority muxs default covers all remaining choice options
Verilog
Case sensitive:
Identifiers and keywords are case sensitive, e.g. sun and SUM refer to different data objects. Mind this when working on mixed HDL designs
-- This is a Comment
Bit Strings
B1100_1001 -- Binary representation XC9 -- Hex representation
Bit Strings
8b1100_1001 8hc9
Comparison Conclusions
Both Languages are well equipped for modeling digital synchronous circuits Both are well supported by Simulation and Synthesis CAD tools VHDL is more strongly typed than Verilog and thus places extra restrictions on the modeling of integrated circuits (many data types, required conversions between types, etc.) Verilog easier to learn for the 1st time user, but more prone to mistakes due to careless modelling (VHDL more robust in this sense) Verilog more C like. VHDL heavily based on Ada VHDL offers bigger variety of concurrent constructs, as well as high level modeling constructs (e.g. packages, configurations) Good to know both of them, as mixed HDL designs are frequently used
backend: process (present_state, clock) is begin case present_state is --STATE S1-- Reset State when s1 => scroll_internal <= '0'; backend_reset <= '1'; if (reset = '0' and rdempty = '0') then next_state <= s10; else next_state <= s1; next_state <= s1;
-end if;
seq1: PROCESS (present_state) IS BEGIN case present_state is when s0 => wr_req <= '0'; grn_led <= '0'; red_led <= '1'; frontend_reset <= '1'; if start = '1' then next_state <= s1; else next_state <= s0; end if; when s1 =>
Usually it is a good practice to use reset only in sequential processes. In this example the use of reset in the combinational process is redundant because the state is reset in the sequential process
get_next_state: process(reset, start, state) begin case state is when IDLE => if(start = '0') then next_state <= ENABLED; else next_state <= IDLE; end if; when ENABLED => if(reset = '0') then next_state <= IDLE; else next_state <= ENABLED; end if; end case; end process;
fifo_wr_req handling
control_reg: process(reset, clk_50) begin if(reset = '0') then state <= IDLE; next_addr <= "00000"; fifo_wr_req <= '0'; else if(rising_edge(clk_50)) then if(fifo_full = '0') then state <= next_state; next_addr <= next_addr - '1'; fifo_wr_req <= '1'; end if; end if; end if; end process;
This is a functionality issue. fifo_wr_req is only set during normal operation (without considering reset) without any provision for clearing it.
A unnecessary complex FSM is implemented where every count value is treated as a separate state
In a sequential process like this (C seems to be a clock signal) it is redundant to list any other signals in the sensitivity list apart from the register clock and the asynchronous reset. The value changes of any other signals will not have an effect, unless there is a clock edge present.
Not very clean way of describing a state machine. It seems as if the FSM uses the clock for its synchronization only during the active0 state. Synthesis tools will probably produce strange logic for such descriptions