Sie sind auf Seite 1von 37

Design using HDLs

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

module mux ( a, b, c, d, s0, s1, x );

Verilog

input a, b, c, d, s0, s1; output x; ... endmodule

Parameterized Design Components


VHDL
ENTITY mux IS GENERIC ( W : POSITIVE :=3) PORT ( a, b, c, d : IN BIT_VECTOR (W downto 0); s0 : IN BIT; s1 : IN BIT; x : OUT BIT_VECTOR (W downto 0) ); END mux ARCHITECTURE dataflow OF mux IS ... END dataflow -- Parameterized Instantiations U1: mux GENERIC MAP (8) PORT MAP (d1,d2,d3,d4,s0,s1,out);

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

// Parameterized instantiations mux #(7) mx1(d1,d2,d3,d4,s0,s1,out); mux #(1) mx2(f1,f2,f3,f4,s0,s1,out);

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

bit : integer : real* :

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;
*

Not supported by Synthesis tools

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);

or subtypes: SUBTYPE scale IS integer RANGE 1024 TO +1024;

library ieee; use ieee.std_logic_1164.all;

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

Declaration wire [15:0] word; wire [1:3] matrix3x2 [1:2]

Array access word[1]; matrix3x2[2][3];

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)

in, out, inout (Used as signals)

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

AND OR NOT XOR NAND NOR XNOR

&& / & || / | !/~ N.A / ^ N.A. N.A. N.A / ~^

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.

SLL SRL SLA SRA ROL ROR

<< >> N.A. N.A N.A. 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) );

Combinational Procedures as Concurrent Statements


VHDL
Combinational process:
PROCESS (a, b, c) BEGIN IF (c = 1) THEN out <= a; ELSE out <= b; END IF; END PROCESS;

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

Clocked Procedures as Concurrent Statements


VHDL
Sequential process:
PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (c = 1) THEN out <= a; END IF; END IF; END PROCESS; Sensitivity list must only contain clock signal

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 (=)

Use non-blocking for sequential procedures

Combinatorial vs Sequential Process


PROCESS (a, b, c) BEGIN IF (c = 1) THEN tmp <= a + b; out <= tmp + c; ELSE tmp <= a - b; out <= tmp c; END IF; END PROCESS; PROCESS (clk) BEGIN IF rising_edge(clk) THEN IF (c=1) THEN tmp <= a + b; out <= tmp + c; ELSE tmp <= a - b; out <= tmp c; END IF; END IF; END PROCESS;

Result is ready 2 cycles later!

Synchronous / Asynchronous Reset in Clocked Procedures


VHDL
Synchronous Reset:
PROCESS (clk) BEGIN IF (clkEVENT AND clk = 1) THEN IF (rst = 1) THEN out <= 0; ELSE out <= a; END IF; END IF; END PROCESS;

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

Types of Procedural Assignments


VHDL
Both Variables and Signals can be assigned within procedures <= signal assignments Evaluated in parallel regardless of their order Should be preferred in sequential procedures to implement flip-flops

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

Signal vs Variable Assignment


PROCESS (a, b, c) BEGIN VARIABLE M, N : integer; M := a; N := b; z <= M + N; M := c ; y <= M + N; END PROCESS; PROCESS (a, b, c, M, N) BEGIN M <= a; N <= b; z <= M + N; M <= c; y <= M + N; END PROCESS;

Signal vs Variable Assignment


PROCESS (a, b, c) BEGIN VARIABLE M, N : integer; M := a; N := b; z <= M + N; M := c ; y <= M + N; END PROCESS; PROCESS (a, b, c, M, N) BEGIN M <= a; N <= b; z <= M + N; M <= c; y <= M + N; END PROCESS;

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;

case (x) 4b0000 4b0111, 4b1001 default endcase

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

Misc. syntax differences


VHDL
Case Insensitive:
Identifiers and keywords are case insensitive, e.g. sum and SUM refer to the same data object

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

// This is a Comment /* This is also


a comment */

Bit Strings
B1100_1001 -- Binary representation XC9 -- Hex representation

Bit Strings
8b1100_1001 8hc9

Binary Divide by 5 FSM


This is a simple FSM for which current state is the running remainder. Output is the bit by bit dividend.

entity divby5 is port ( x, clk : in std_logic; y : out std_logic; end divby5

FSM (in VHDL)


architecture state_machine of divby5 is type StateType is (state0, state1, state2, state3, state4); signal p_s, n_s : StateType; begin fsm: process(p_s,x) begin case p_s is when state0 => y <= '0'; if x = '1' then n_s <= state1; else n_s <= state0; end if; when state1 => y <= '0'; if x = '1' then n_s <= state3; else n_s <= state2; end if; when state2 => if x = '1' then n_s <= state0; y <= '1'; else n_s <= state4; y <= '0'; end if; when state3 => y <= '1'; if x='1' then n_s <= state2; else n_s <= state1; end if; when state4 => y <= '1'; if x = '1' then n_s <= state4; else n_s <= state3; end if; -- avoid trap states when others => n_s <= state0; end case end process fsm; state_clocked : process(clk) begin if rising_edge(clk) then p_s <= n_s; end if; end process state_clocked; end architecture state machine;

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

Real Student Design Pitfalls


A summary of some design styles that were used in past student projects, which caused unexpected behavior or other side effects

No clock edge detection:



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;

Process is triggered for both falling and rising edges of clock

Sensitivity list issues:



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 =>

Incomplete sensitivity lists can lead to simulation-synthesis mismatches

Redundant use of Reset in combinational process:


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;

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.

Enumeration of all counter states:


get_next_state: process (fifo_full, reset, start, state) begin case state is when IDLE => if (start = '0') then next_state <= S31; else next_state <= IDLE; end if; when S31 => if (reset = '0') then next_state <= IDLE; elsif (fifo_full = '0') then next_state <= S30; else next_state <= S31; end if; when S30 => if (reset = '0') then next_state <= IDLE; elsif (fifo_full = '0') then next_state <= S29; else next_state <= S30; end if; when S29 => if (reset = '0') then next_state <= IDLE; elsif (fifo_full = '0') then next_state <= S28; else next_state <= S29; end if; when S28 => if (reset = '0') then next_state <= IDLE; elsif (fifo_full = '0') then next_state <= S27; else next_state <= S28; end if;

A unnecessary complex FSM is implemented where every count value is treated as a separate state

Redundant Sensitivity signals


process(C, reset,start,input) begin if reset='1' then tmp<=(others =>'0'); elsif C='0' and C'event then if start='1' then tmp <= tmp(27 downto 0)& input(3 downto 0); end if; end if;

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.

Clock detection in case clause:


process(clk50,present_state,counter,wr_full) begin case present_state is when idle => temp_addr<=(others =>'0'); when active0 => if clk50='0' and clk50'event then if wr_full='0' then temp_addr<=temp_addr-1; end if; end if; when others => null; end case; end process;

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

Das könnte Ihnen auch gefallen