Part III: VHDL CODING
٢٢/٠٣/١٤٣٥
Part III: VHDL CODING
1
Design Structure
Data Types
Operators and Attributes
Concurrent Design
A VHDL Primer:
The Essentials
Problem
(Design &
Implementation)
Additional
Circuit Designs
Applications
Sequential Design
Signals and Variables
State Machines
2
١
٢٢/٠٣/١٤٣٥
Sequential Design
PROCESS
Signals and Variables
IF
WAIT
CASE
LOOP
CASE versus IF
CASE versus WHEN
Bad Clocking
Using Sequential Code to Design Combinational Circuits
3
PROCESS
A PROCESS is a sequential section of VHDL code. It is characterized by the presence of IF,
WAIT, CASE, or LOOP, and by a sensitivity list (except when WAIT is used). A PROCESS
must be installed in the main code, and is executed every time a signal in the sensitivity list
changes (or the condition related to WAIT is fulfilled). Its syntax is shown below:
[label:] PROCESS (sensitivity list)
[VARIABLE name type [range] [:= initial_value;]]
BEGIN
(sequential code)
END PROCESS [label];
-- VARIABLES are optional
4
٢
٢٢/٠٣/١٤٣٥
Example : DFF with Asynchronous Reset #1
1 -------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------5 ENTITY dff IS
6
PORT (d, clk, rst: IN STD_LOGIC;
7
q: OUT STD_LOGIC);
8 END dff;
9 -------------------------------------10 ARCHITECTURE behavior OF dff IS
11 BEGIN
12
PROCESS (clk, rst)
13
BEGIN
14
IF (rst='1') THEN
15
q <= '0';
16
ELSIF (clk'EVENT AND clk='1') THEN
17
q <= d;
18
END IF;
19
END PROCESS;
20 END behavior;
21 --------------------------------------
5
Signals and Variables
1. SIGNAL can be declared in a PACKAGE, ENTITY or ARCHITECTURE (in
its declarative part)
2. Can be global
3. Can
4. When used in a PROCESS, updating occur after the conclusion of the present run
of the PROCESS
5. assignment operator “<=“ ( sig <= 3)
1. VARIABLE can only be declared inside a piece of sequential code (in a
PROCESS, for example)
2. always local
3. Variable can never be passed out of the PROCESS directly; if necessary, then it
must be assigned to a SIGNAL
4. Update of a VARIABLE is immediate
5. assignment operator “:=“ (var := 3)
6
٣
٢٢/٠٣/١٤٣٥
IF
IF conditions THEN assignments;
ELSIF conditions THEN assignments;
...
ELSE assignments;
END IF;
Example:
IF (x<y) THEN temp:="11111111";
ELSIF (x=y AND w='0') THEN
temp:="11110000";
ELSE temp:=(OTHERS =>'0');
7
Example: One-digit Counter #1
1 --------------------------------------------1-digit decimal counter (0 to 9 to 0).
2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 --------------------------------------------5 ENTITY counter IS
6
PORT (clk : IN STD_LOGIC;
7
digit : OUT INTEGER RANGE 0 TO 9);
8 END counter;
9 --------------------------------------------10 ARCHITECTURE counter OF counter IS
11 BEGIN
12
count: PROCESS(clk)
13
VARIABLE temp : INTEGER RANGE 0 TO 10;
14
BEGIN
15
IF (clk'EVENT AND clk='1') THEN
16
temp := temp + 1;
17
IF (temp=10) THEN temp := 0;
18
END IF;
19
END IF;
20
digit <= temp;
21
END PROCESS count;
22 END counter;
23 ---------------------------------------------
٤
8
٢٢/٠٣/١٤٣٥
Example: Shift Register
1 -------------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------------------5 ENTITY shiftreg IS
6
GENERIC (n: INTEGER := 4); -- # of stages
7
PORT (d, clk, rst: IN STD_LOGIC;
8
q: OUT STD_LOGIC);
9 END shiftreg;
10 -------------------------------------------------11 ARCHITECTURE behavior OF shiftreg IS
12
SIGNAL internal: STD_LOGIC_VECTOR (n-1 DOWNTO 0);
13 BEGIN
14
PROCESS (clk, rst)
15
BEGIN
16
IF (rst='1') THEN
17
internal <= (OTHERS => '0');
18
ELSIF (clk'EVENT AND clk='1') THEN
19
internal <= d & internal(internal'LEFT DOWNTO 1);
20
END IF;
21
END PROCESS;
22
q <= internal(0);
23 END behavior;
24 --------------------------------------------------
9
WAIT
WAIT UNTIL signal_condition;
WAIT ON signal1 [ , signal2, ... ];
PROCESS cannot have a sensitivity list when WAIT
is employed.
WAIT FOR time;
Example: 8-bit register with synchronous reset
WAIT UNTIL must be the first statement in
the PROCESS. The PROCESS will be
executed every time the condition is met.
PROCESS
-- no sensitivity list
BEGIN
WAIT UNTIL (clk'EVENT AND clk='1');
IF (rst='1') THEN
output <= "00000000";
ELSIF (clk'EVENT AND clk='1') THEN
output <= input;
END IF;
END PROCESS;
10
٥
٢٢/٠٣/١٤٣٥
WAIT ON, on the other hand, accepts multiple signals. The PROCESS is put on hold
until any of the signals listed changes. In the example below, the PROCESS will
continue execution whenever a change in rst or clk occurs.
Example: 8-bit register with asynchronous reset
PROCESS
BEGIN
WAIT ON clk, rst;
IF (rst='1') THEN
output <= "00000000";
ELSIF (clk'EVENT AND clk='1') THEN
output <= input;
END IF;
END PROCESS;
WAIT FOR is intended for simulation only
(waveform generation for test benches).
Example: WAIT FOR 5ns;
11
Example: DFF with Asynchronous Reset #2
1 -------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------5 ENTITY dff IS
6
PORT (d, clk, rst: IN STD_LOGIC;
7
q: OUT STD_LOGIC);
8 END dff;
9 -------------------------------------10 ARCHITECTURE dff OF dff IS
11 BEGIN
12
PROCESS
13
BEGIN
14
WAIT ON rst, clk;
15
IF (rst='1') THEN
16
q <= '0';
17
ELSIF (clk'EVENT AND clk='1') THEN
18
q <= d;
19
END IF;
20
END PROCESS;
21 END dff;
22 --------------------------------------
٦
Example: One-digit Counter #2
1 --------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 --------------------------------------------5 ENTITY counter IS
6
PORT (clk : IN STD_LOGIC;
7
digit : OUT INTEGER RANGE 0 TO 9);
8 END counter;
9 --------------------------------------------10 ARCHITECTURE counter OF counter IS
11 BEGIN
12
PROCESS -- no sensitivity list
13
VARIABLE temp : INTEGER RANGE 0 TO 10;
14
BEGIN
15
WAIT UNTIL (clk'EVENT AND clk='1');
16
temp := temp + 1;
17
IF (temp=10) THEN temp := 0;
18
END IF;
19
digit <= temp;
20
END PROCESS;
21 END counter;
22 --------------------------------------------12
٢٢/٠٣/١٤٣٥
CASE
CASE identifier IS
WHEN value => assignments;
WHEN value => assignments;
...
END CASE;
CASE statement (sequential) is very similar to WHEN (combinational).
CASE allows multiple assignments for each test condition
WHEN allows only one
Example:
CASE control IS
WHEN "00" => x<=a; y<=b;
WHEN "01" => x<=b; y<=c;
WHEN OTHERS => x<="0000"; y<="ZZZZ";
END CASE;
WHEN value -- single value
WHEN value1 to value2
WHEN value1 | value2 |...
-- range, for enumerated data types only
-- value1 or value2 or ...
13
Example: DFF with Asynchronous Reset #3
1 ---------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 ---------------------------------------------5 ENTITY dff IS
6
PORT (d, clk, rst: IN BIT;
7
q: OUT BIT);
8 END dff;
9 ---------------------------------------------10 ARCHITECTURE dff3 OF dff IS
11 BEGIN
12
PROCESS (clk, rst)
13
BEGIN
14
CASE rst IS
15
WHEN '1' => q<='0';
16
WHEN '0' =>
17
IF (clk'EVENT AND clk='1') THEN
18
q <= d;
19
END IF;
20
WHEN OTHERS => NULL;
21
END CASE;
22 END PROCESS;
23 END dff3;
24 ----------------------------------------------
14
٧
٢٢/٠٣/١٤٣٥
Example: Two-digit Counter with SSD Output
1 -------------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------------------5 ENTITY counter IS
6
PORT (clk, reset : IN STD_LOGIC;
7
digit1, digit2 : OUT STD_LOGIC_VECTOR (6 DOWNTO 0));
8 END counter;
9 -------------------------------------------------10 ARCHITECTURE counter OF counter IS
11 BEGIN
12
PROCESS(clk, reset)
13
VARIABLE temp1: INTEGER RANGE 0 TO 10;
14
VARIABLE temp2: INTEGER RANGE 0 TO 10;
15
BEGIN
16 ---- counter: ---------------------17
IF (reset='1') THEN
18
temp1 := 0;
19
temp2 := 0;
20
ELSIF (clk'EVENT AND clk='1') THEN
21
temp1 := temp1 + 1;
22
IF (temp1=10) THEN
23
temp1 := 0;
24
temp2 := temp2 + 1;
25
IF (temp2=10) THEN
26
temp2 := 0;
27
END IF;
28
END IF;
29
END IF;
30 ---- BCD to SSD conversion: -------31
CASE temp1 IS
32
WHEN 0 => digit1 <= "1111110"; --7E
33
WHEN 1 => digit1 <= "0110000"; --30
34
WHEN 2 => digit1 <= "1101101"; --6D
35
WHEN 3 => digit1 <= "1111001"; --79
36
WHEN 4 => digit1 <= "0110011"; --33
37
WHEN 5 => digit1 <= "1011011"; --5B
38
WHEN 6 => digit1 <= "1011111"; --5F
39
WHEN 7 => digit1 <= "1110000"; --70
40
WHEN 8 => digit1 <= "1111111"; --7F
41
WHEN 9 => digit1 <= "1111011"; --7B
42
WHEN OTHERS => NULL;
43
END CASE;
44
CASE temp2 IS
45
WHEN 0 => digit2 <= "1111110"; --7E
46
WHEN 1 => digit2 <= "0110000"; --30
47
WHEN 2 => digit2 <= "1101101"; --6D
48
WHEN 3 => digit2 <= "1111001"; --79
49
WHEN 4 => digit2 <= "0110011"; --33
50
WHEN 5 => digit2 <= "1011011"; --5B
51
WHEN 6 => digit2 <= "1011111"; --5F
52
WHEN 7 => digit2 <= "1110000"; --70
53
WHEN 8 => digit2 <= "1111111"; --7F
54
WHEN 9 => digit2 <= "1111011"; --7B
55
WHEN OTHERS => NULL;
56
END CASE;
57
END PROCESS;
58 END counter;
59 -------------------------------------------------15
16
٨
٢٢/٠٣/١٤٣٥
LOOP
FOR / LOOP: The loop is repeated a fixed number of times.
[label:] FOR identifier IN range LOOP
(sequential statements)
END LOOP [label];
EXIT: Used for ending the loop.
[label:] EXIT [label] [WHEN condition];
WHILE / LOOP: The loop is repeated until a condition no longer
holds.
[label:] WHILE condition LOOP
(sequential statements)
END LOOP [label];
NEXT: Used for skipping loop steps.
[label:] NEXT [loop_label] [WHEN condition];
17
Example of FOR / LOOP:
FOR i IN 0 TO 5 LOOP
x(i) <= enable AND w(i+2);
y(0, i) <= w(i);
END LOOP;
Example with EXIT:
FOR i IN data'RANGE LOOP
CASE data(i) IS
WHEN '0' => count:=count+1;
WHEN OTHERS => EXIT;
END CASE;
END LOOP;
Example of WHILE / LOOP:
WHILE (i < 10) LOOP
WAIT UNTIL clk'EVENT AND clk='1';
(other statements)
END LOOP;
Example with NEXT:
FOR i IN 0 TO 15 LOOP
NEXT WHEN i=skip; -- jumps to next iteration
(...)
END LOOP;
٩
18
٢٢/٠٣/١٤٣٥
Example: Carry Ripple Adder
8-bit unsigned carry ripple adder
19
1 ----- Solution 1: Generic, with VECTORS -------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -----------------------------------------------5 ENTITY adder IS
6
GENERIC (length : INTEGER := 8);
7
PORT ( a, b: IN STD_LOGIC_VECTOR (length-1 DOWNTO 0);
8
cin: IN STD_LOGIC;
9
s: OUT STD_LOGIC_VECTOR (length-1 DOWNTO 0);
10
cout: OUT STD_LOGIC);
11 END adder;
12 -----------------------------------------------13 ARCHITECTURE adder OF adder IS
14 BEGIN
15
PROCESS (a, b, cin)
16
VARIABLE carry : STD_LOGIC_VECTOR (length DOWNTO 0);
17
BEGIN
18
carry(0) := cin;
19
FOR i IN 0 TO length-1 LOOP
20
s(i) <= a(i) XOR b(i) XOR carry(i);
21
carry(i+1) := (a(i) AND b(i)) OR (a(i) AND
22
carry(i)) OR (b(i) AND carry(i));
23
END LOOP;
24
cout <= carry(length);
25
END PROCESS;
26 END adder;
27 ------------------------------------------------
1 ---- Solution 2: non-generic, with INTEGERS ---2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -----------------------------------------------5 ENTITY adder IS
6
PORT ( a, b: IN INTEGER RANGE 0 TO 255;
7
c0: IN STD_LOGIC;
8
s: OUT INTEGER RANGE 0 TO 255;
9
c8: OUT STD_LOGIC);
10 END adder;
11 -----------------------------------------------12 ARCHITECTURE adder OF adder IS
13 BEGIN
14
PROCESS (a, b, c0)
15
VARIABLE temp : INTEGER RANGE 0 TO 511;
16
BEGIN
17
IF (c0='1') THEN temp:=1;
18
ELSE temp:=0;
19
END IF;
20
temp := a + b + temp;
21
IF (temp > 255) THEN
22
c8 <= '1';
23
temp := temp---256;
24
ELSE c8 <= '0';
25
END IF;
26
s <= temp;
27
END PROCESS;
28 END adder;
29 -----------------------------------------------20
١٠
٢٢/٠٣/١٤٣٥
21
Example: Simple Barrel Shifter
1 --------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 --------------------------------------------5 ENTITY barrel IS
6
GENERIC (n: INTEGER := 8);
7
PORT ( inp: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0);
8
shift: IN INTEGER RANGE 0 TO 1;
9
outp: OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0));
10 END barrel;
11 --------------------------------------------12 ARCHITECTURE RTL OF barrel IS
13 BEGIN
14
PROCESS (inp, shift)
15
BEGIN
16
IF (shift=0) THEN
17
outp <= inp;
18
ELSE
19
outp(0) <= '0';
20
FOR i IN 1 TO inp'HIGH LOOP
21
outp(i) <= inp(i-1);
22
END LOOP;
23
END IF;
24
END PROCESS;
25 END RTL;
26 ---------------------------------------------
22
١١
٢٢/٠٣/١٤٣٥
23
Example: Leading Zeros
1 -------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------------5 ENTITY LeadingZeros IS
6
PORT ( data: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
7
zeros: OUT INTEGER RANGE 0 TO 8);
8 END LeadingZeros;
9 -------------------------------------------10 ARCHITECTURE behavior OF LeadingZeros IS
11 BEGIN
12
PROCESS (data)
13
VARIABLE count: INTEGER RANGE 0 TO 8;
14
BEGIN
15
count := 0;
16
FOR i IN data'RANGE LOOP
17
CASE data(i) IS
18
WHEN '0' => count := count + 1;
19
WHEN OTHERS => EXIT;
20
END CASE;
21
END LOOP;
22
zeros <= count;
23
END PROCESS;
24 END behavior;
25 --------------------------------------------
١٢
24
٢٢/٠٣/١٤٣٥
CASE versus IF
Example: The codes below implement the same physical multiplexer circuit.
--------------With IF: ------------IF (sel="00") THEN x<=a;
ELSIF (sel="01") THEN x<=b;
ELSIF (sel="10") THEN x<=c;
ELSE x<=d;
-------- With CASE: -----------CASE sel IS
WHEN "00" => x<=a;
WHEN "01" => x<=b;
WHEN "10" => x<=c;
WHEN OTHERS => x<=d;
END CASE;
25
CASE versus WHEN
26
١٣
٢٢/٠٣/١٤٣٥
Example: From a functional point of view, the two codes below are equivalent.
---- With WHEN: ----------------
---- With CASE: ----------------
WITH sel SELECT
x <= a WHEN "000",
b WHEN "001",
c WHEN "010",
UNAFFECTED WHEN OTHERS;
CASE sel IS
WHEN "000" => x<=a;
WHEN "001" => x<=b;
WHEN "010" => x<=c;
WHEN OTHERS => NULL;
END CASE;
--------------------------------
27
Bad Clocking
The compiler will generally not be able to synthesize codes that contain assignments to the
same signal at both transitions of the reference (clock) signal (that is, at the rising edge plus
at the falling edge).
PROCESS (clk)
BEGIN
IF(clk'EVENT AND clk='1') THEN
counter <= counter + 1;
ELSIF(clk'EVENT AND clk='0') THEN
counter <= counter + 1;
END IF;
...
END PROCESS;
Also
Signal counter is multiply driven.
28
١٤
٢٢/٠٣/١٤٣٥
EVENT attribute must be related to a test condition
PROCESS (clk)
BEGIN
IF(clk'EVENT) THEN
counter := counter + 1;
END IF;
...
END PROCESS;
If a signal appears in the sensitivity list, but does not appear in any of the assignments that
compose the PROCESS
PROCESS (clk)
BEGIN
counter := counter + 1;
...
END PROCESS;
29
----------------------------------------------------PROCESS (clk)
BEGIN
IF(clk'EVENT AND clk='1') THEN
x <= d;
END IF;
END PROCESS;
-----------------------------------------------------
----------------------------------------------------PROCESS (clk)
BEGIN
IF(clk'EVENT AND clk='0') THEN
y <= d;
END IF;
END PROCESS;
-----------------------------------------------------
30
١٥
٢٢/٠٣/١٤٣٥
Example: RAM
31
1 --------------------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 --------------------------------------------------5 ENTITY ram IS
6 GENERIC ( bits: INTEGER := 8; -- # of bits per word
7
words: INTEGER := 16); -- # of words in the memory
8
PORT ( wr_ena, clk: IN STD_LOGIC;
9
addr: IN INTEGER RANGE 0 TO words-1;
10
data_in: IN STD_LOGIC_VECTOR (bits-1 DOWNTO 0);
11
data_out: OUT STD_LOGIC_VECTOR (bits-1 DOWNTO 0));
12 END ram;
13 --------------------------------------------------14 ARCHITECTURE ram OF ram IS
15
TYPE vector_array IS ARRAY (0 TO words-1) OF
16
STD_LOGIC_VECTOR (bits-1 DOWNTO 0);
17
SIGNAL memory: vector_array;
18 BEGIN
19
PROCESS (clk, wr_ena)
20
BEGIN
21
IF (wr_ena='1') THEN
22
IF (clk'EVENT AND clk='1') THEN
23
memory(addr) <= data_in;
24
END IF;
25
END IF;
26
END PROCESS;
27
data_out <= memory(addr);
28 END ram;
29 ---------------------------------------------------
32
١٦
٢٢/٠٣/١٤٣٥
Using Sequential Code to Design Combinational Circuits
Rule 1: Make sure that all input signals used (read) in the PROCESS appear in its sensitivity list.
Generally cause the compiler to simply issue a warning
Rule 2: Make sure that all combinations of the input/output signals are included in the code
Consequences can be more serious
33
Example: Bad Combinational Design
34
١٧
٢٢/٠٣/١٤٣٥
1 -------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------5 ENTITY example IS
6
PORT (a, b, c, d: IN STD_LOGIC;
7
sel: IN INTEGER RANGE 0 TO 3;
8
x, y: OUT STD_LOGIC);
9 END example;
10 -------------------------------------11 ARCHITECTURE example OF example IS
12 BEGIN
13
PROCESS (a, b, c, d, sel)
14
BEGIN
15
IF (sel=0) THEN
16
x<=a;
17
y<='0';
18
ELSIF (sel=1) THEN
19
x<=b;
20
y<='1';
21
ELSIF (sel=2) THEN
22
x<=c;
23
ELSE
24
x<=d;
25
END IF;
26
END PROCESS;
27 END example;
28 --------------------------------------
1 -------------------------------------2 LIBRARY ieee;
3 USE ieee.std_logic_1164.all;
4 -------------------------------------5 ENTITY example IS
6
PORT (a, b, c, d: IN STD_LOGIC;
7
sel: IN INTEGER RANGE 0 TO 3;
8
x, y: OUT STD_LOGIC);
9 END example;
10 -------------------------------------11 ARCHITECTURE example OF example IS
12 BEGIN
13
PROCESS (a, b, c, d, sel)
14
BEGIN
15
IF (sel=0) THEN
16
x<=a;
17
y<='0';
18
ELSIF (sel=1) THEN
19
x<=b;
20
y<='1';
21
ELSIF (sel=2) THEN
22
x<=c;
23
y<='X';
24
ELSE
25
x<=d;
26
y<='X';
27
END IF;
28
END PROCESS;
29 END example;
30 --------------------------------------
latch
35
36
١٨
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement