-
Notifications
You must be signed in to change notification settings - Fork 65
/
chapter4.tex
627 lines (547 loc) · 44.5 KB
/
chapter4.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
% Free range VHDL
% Authors: Bryan Mealy, Fabrizio Tappero
% Date: January, 2023
% URL: https://github.com/fabriziotappero/Free-Range-VHDL-book
% (C) 2018-2023 B. Mealy, F. Tappero
%
% !TEX root = master.tex
%
\chapter{VHDL Programming Paradigm}
The previous chapter introduced the idea of the basic design units of VHDL: the entity and the architecture. Most of the time was spent describing the entity simply because there is so much less involved compared to the architecture. Remember, the entity declaration is used to describe the interface of a circuit to the outside world. The architecture is used to describe how the circuit is intended to function.
Before we get into the details of architecture specification, we must step back for a moment and remember what it is we are trying to do with VHDL. We are, for one reason or another, describing a digital circuit. Realizing this is very important. The tendency for young VHDL programmers with computer programming backgrounds is to view VHDL as just another programming language they want or have to learn. Although many university students have used this approach to pass the basic digital classes, this is not a good idea.
When viewed correctly, VHDL represents a completely different approach to programming while still having many similarities to other programming languages. The main similarity is that they both use a syntactical and rule-based language to describe something abstract. But, the difference is that they are describing two different things. Most programming languages are used to implement functionalities in a sequential manner, one instruction at a time. VHDL however describes hardware and so instructions are executed in a concurrent manner\footnote{In VHDL, there are ways to obtain sequential execution as well.}, meaning that all instructions are executed at once. Realizing this fact will help you to truly understand the VHDL programming paradigm and language.
\section{Concurrent Statements}
At the heart of most programming languages are the statements that form a majority of the associated source code. These statements represent finite quantities of actions to be taken. A statement in an algorithmic programming language such as C or Java represents an action to be taken by the processor. Once the processor finishes one action, it moves onto the next action specified somewhere in the associated source code. This makes sense and is comfortable to us as humans because just like the processor, we are generally only capable of doing one thing at a time. This description lays the foundation for an algorithmic method where the processor does a great job of following a set of rules which are essentially the direction provided by the source code. When the rules are meaningful, the processor can do amazing things.
VHDL programming is significantly different. Whereas a processor steps one by one through a set of statements, VHDL has the ability to execute a virtually unlimited number of statements at the same time and in a concurrent manner (in other words, in parallel). Once again, the key thing to remember here is that we are designing hardware. Parallelism, or things happening concurrently, in the context of hardware is a much more straightforward concept than it is in the world of software. If you have had any introduction to basic digital hardware, you are most likely already both familiar and comfortable with the concept of parallelism, albeit not within a programming language.
\begin{figure}
\centering
\usetikzlibrary{er}
\begin{tikzpicture}[minimum height=9mm,scale=0.9]
\node[draw, and gate US] at (0,0.2) (C) {C};
\node[draw, not gate US] at ([xshift=-1.95cm]C.input 2) (D) {D};
\node[draw, or gate US] at (0,1.3) (B) {B};
\node[draw, and gate US] at (0,2.4) (A) {A};
\node[draw, or gate US] at (2.5,1.3) (E) {E};
\draw (D.output) -- (C.input 2);
\draw (A.output) -- +(0.7,0) |- (E.input 1);
\draw (C.output) -- +(0.7,0) |- (E.input 2);
\draw (B.output) -- (E.west);
\draw (E.output) -- ([xshift=1cm]E.output) node [pos=1.6] {E\_out} ;
\draw (A.input 1) -- ([xshift=-4.cm]A.input 1) node [pos=1.1] {A\_1} ;
\draw (A.input 2) -- ([xshift=-4.cm]A.input 2) node [pos=1.1] {A\_2} ;
\draw (B.input 1) -- ([xshift=-4.1cm]B.input 1) node [pos=1.1] {B\_1} ;
\draw (B.input 2) -- ([xshift=-4.1cm]B.input 2) node [pos=1.1] {B\_2} ;
\draw (D.input) -- ([xshift=-2.9cm]D.output) node [pos=1.25] {D\_1} ;
\node [circle,fill, inner sep=0pt,minimum size=1.2mm] at ([xshift=-6mm]B.input 2) (H) {}; %dot
\draw (C.input 1) -| (H);
\draw [dashed] (-3.5,-0.65) rectangle (3.5,3.1) node [pos=0.93, auto=left] {my\_circuit} ;
\end{tikzpicture}
\caption{Some common circuit that is well known to \texttt{execute} parallel operations.}
\label{concurrent_circuit}
\end{figure}
Figure~\ref{concurrent_circuit} shows a simple example of a circuit that operates in parallel. As you know, the output of the gates are a function of the gate inputs. Any time that any gate input changes, there is a possibility that, after an opportune delay, the gate output will change. This is true of all the gates in Figure~\ref{concurrent_circuit} or in any digital circuit in general. Once changes to the gate inputs occur, the circuit status is re-evaluated and the gate outputs may change accordingly. Although the circuit in Figure~\ref{concurrent_circuit} only shows a few gates, this idea of concurrent operation of all the elements in the circuit is the same in all digital circuits no matter how large or complex they are.
Since most of us are human, we are only capable of reading one line of text at a time and in a sequential manner. We have the same limitation when we try to write some text, not to mention enter some text into a computer. So how then are we going to use text to describe a circuit that is inherently parallel? We did not have this problem when discussing something inherently sequential such as standard algorithmic programming. When writing code using an algorithmic programming language, there is generally only one processing element to focus on at each given time. Everything more or less follows up in a sequential manner, which fits nicely with our basic limitation as humans.
The VHDL programming paradigm is built around the concept of expression parallelism and concurrency with textual descriptions of circuits. The heart of VHDL programming is the concurrent statement. These are statements that look a lot like the statements in algorithmic languages but they are significantly different because the VHDL statements, by definition, express concurrency of execution.
\begin{lstlisting}[float, label=parallel_code, caption=VHDL code for the circuit of Figure 4.1.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_circuit is
port ( A_1,A_2,B_1,B_2,D_1 : in std_logic;
E_out : out std_logic);
end my_circuit;
-- architecture
architecture my_circuit_arc of my_circuit is
signal A_out, B_out, C_out : std_logic;
begin
A_out <= A_1 and A_2;
B_out <= B_1 or B_2;
C_out <= (not D_1) and B_2;
E_out <= A_out or B_out or C_out;
end my_circuit_arc;
\end{lstlisting}
Listing~\ref{parallel_code} shows the code that implements the circuit shown in Figure~\ref{concurrent_circuit}. This code shows four concurrent signal assignment statements. As seen before, the ``$<=$'' construct refers to the signal assignment operator. It is true that we cannot write these four statements at the same time but we can interpret these statements as actions that occur concurrently. Remember to keep in mind that the concept of concurrency is a key concept in VHDL. If you feel that the algorithmic style of thought is creeping into your soul, try to snap out of it quickly. The concurrent signal assignment is discussed in greater detail in the next section.
As a consequence of the concurrent nature of VHDL statements, the three chunks of code appearing below are 100\% equivalent to the code shown in Listing~\ref{parallel_code}. Once again, since the statements are interpreted as occurring concurrently: the order that these statements appear in your VHDL source code makes no difference. Generally speaking, it would be a better idea to describe the circuit as shown in Listing~\ref{parallel_code} since it somewhat reflects the natural organization of statements.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=parallel_code_2, caption=Equivalent VHDL code for the circuit of Figure 4.1. ]
C_out <= (not D_1) and B_2;
A_out <= A_1 and A_2;
B_out <= B_1 or B_2;
E_out <= A_out or B_out or C_out;
\end{lstlisting}
\begin{lstlisting}[label=parallel_code_3, caption=Equivalent VHDL code for the circuit of Figure 4.1.]
A_out <= A_1 and A_2;
E_out <= A_out or B_out or C_out;
B_out <= B_1 or B_2;
C_out <= (not D_1) and B_2;
\end{lstlisting}
\begin{lstlisting}[label=parallel_code_4, caption=Equivalent VHDL code for the circuit of Figure 4.1.]
B_out <= B_1 or B_2;
A_out <= A_1 and A_2;
E_out <= A_out or B_out or C_out;
C_out <= (not D_1) and B_2;
\end{lstlisting}
\end{minipage}
\section{Signal Assignment Operator \texorpdfstring{``$<=$''}{<=}}
Algorithmic programming languages always have some type of assignment operator. In C or Java, this is the well-known ``='' sign. In these languages, the assignment operator signifies a transfer of data from the right-hand side of the operator to the left-hand side. VHDL uses two consecutive characters to represent the assignment operator: ``\texttt{$<=$}''. This combination was chosen because it is different from the assignment operators in most other common algorithmic programming languages. The operator is officially known as a signal assignment operator to highlight its true purpose. The signal assignment operator specifies a relationship between signals. In other words, the signal on the left-hand side of the signal assignment operator is dependent upon the signals on the right-hand side of the operator.
With these new insights into VHDL, you should be able to understand the code of Listing~\ref{parallel_code} and its relationship to its schematic shown in Figure~\ref{concurrent_circuit}. The statement ``\texttt{G~$<=$~A~AND~B;}'' indicates that the value of the signal named \texttt{G} represents an AND logic operation between the signals \texttt{A} and \texttt{B}.
There are four types of concurrent statements that are examined in this chapter. We have already briefly discussed the concurrent signal assignment statement which we will soon examine further and put it into the context of an actual circuit. The three other types of concurrent statements that are of immediate interest to us are the process statement, the conditional signal assignment and the selected signal assignment.
In essence, the four types of statements represent the tools that you will use to implement digital circuits in VHDL. You will soon be discovering the versatility of these statements. Unfortunately, this versatility effectively adds a fair amount of steepness to the learning curve. As you know from your experience in other programming languages, there are always multiple ways to do the same things. Stated differently, several seemingly different pieces of code can actually produce the same result. The same is true for VHDL code: several considerably different pieces of VHDL code can actually generate the exact same hardware. Keep this in mind when you look at any of the examples given in this tutorial. Any VHDL code used to solve a problem is more than likely one of many possible solutions to that problem. Some of the VHDL models in this tutorial are presented to show that something can be done a certain way, but that does not necessarily mean they can only be done in that way.
\section{Concurrent Signal Assignment Statements}
The general form of a concurrent signal assignment statement is shown in Listing~\ref{concurrent_sig_assig}. In this case, the target is a signal that receives the values of the expression. An expression is defined by a constant, by a signal, or by a set of operators that operate on other signals. Examples of expressions used in VHDL code are shown in the examples that follow.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=concurrent_sig_assig, caption=Syntax for the concurrent signal assignment statement.]
<target> <= <expression>;
\end{lstlisting}
\end{minipage}
\begin{leftbar}
\noindent
\textbf{EXAMPLE 1.}
Write the VHDL code that implements a three-input NAND gate. The three input signals are named A, B and C and the output signal name is F.
\end{leftbar}
\noindent
\textbf{SOLUTION.} It is good practice to always draw a diagram of the circuit you are designing. Furthermore, although we could draw a diagram showing the familiar symbol for the NAND gate, we will choose to keep the diagram general and take the black-box approach instead. Remember, the black box is a nice aid when it comes to writing the entity declaration. The solution to Example~1 is provided in Listing~\ref{example_1}.
\noindent
\begin{minipage}{0.55\linewidth}
\begin{lstlisting}[numbers=left,label=example_1, caption=Solution of Example~1.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_nand3 is
port ( A,B,C : in std_logic;
F : out std_logic);
end my_nand3;
-- architecture
architecture exa_nand3 of my_nand3 is
begin
F <= NOT(A AND B AND C);
end exa_nand3;
\end{lstlisting}
\end{minipage}
\begin{minipage}{0.4\linewidth}
\begin{flushright}
\begin{tikzpicture}[x=1mm,y=1mm,line width=0.8pt,scale=0.9,framed]
%\draw[help lines] (0,0) grid (50,50);
% BOX
\draw (20,2.5) rectangle (40,22.5) node[midway]{my\_nand3};
% INPUTS
\small
\node (b) at (20,25) {}; % this is to extend the pink area
\node (a) at (20,-2.5) {}; % this is the reference point
\draw [latex-] ($(a)+(0,20)$) -- ++(-10,0) node[left]{A};
\draw [latex-] ($(a)+(0,15)$) -- ++(-10,0) node[left]{B};
\draw [latex-] ($(a)+(0,10)$) -- ++(-10,0) node[left]{C};
% OUTPUTS
\draw [-latex] ($(a)+(20,15)$) -- ++(10,0) node[right]{F};
\end{tikzpicture}
\end{flushright}
\end{minipage}
This example contains a few new ideas that are worth further clarification.
\begin{my_list}
\item There are header files and library files that must be included in your VHDL code in order for your code to correctly compile. These few lines of code are listed at the top of the code in Listing~\ref{example_1}. The listed lines are more than what is needed for this example but they will be required in later examples. To save space, these lines will be omitted in some of the coming examples.
\item This example highlights the use of several logic operators. The logic operators available in VHDL are AND, OR, NAND, NOR, XOR and XNOR. The NOT operator is technically not a logic operator but is also available. Moreover, these logic operators are considered to be binary operators in that they operate on the two values appearing on the left and right-hand side of the operator. The NOT operator is a unary operator and for that, it only operates on the value appearing to the right of the operator.
\item In this solution, the entity only has one associated architecture. This is fairly common practice in most VHDL design.
\end{my_list}
Example~1 demonstrates the use of the concurrent signal assignment (CSA) statement in a working VHDL program (refer to line 12 of Listing~\ref{example_1}). But since there is only one CSA statement, the concept of concurrency is not readily apparent. The idea behind any concurrent statement in VHDL is that the output is changed any time one of the input signals changes. In other words, the output F is re-evaluated any time a signal on the input expression changes. This is a key concept in truly understanding the VHDL, so you may want to read that sentence a few more times. The idea of concurrency is more clearly demonstrated in Example~2.
\begin{leftbar}
\noindent
\textbf{EXAMPLE 2.}
Write the VHDL code to implement the function expressed by the following logic equation: $F3=\overline{L} \cdot \overline{M}\cdot N+L\cdot M$
\end{leftbar}
\noindent
\textbf{SOLUTION.} The black box diagram and associated VHDL code is shown in Listing~\ref{example_2}.
\noindent
\begin{minipage}{0.6\linewidth}
\begin{lstlisting}[label=example_2, caption=Solution of Example~2.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_ckt_f3 is
port ( L,M,N : in std_logic;
F3 : out std_logic);
end my_ckt_f3;
-- architecture
architecture f3_2 of my_ckt_f3 is
begin
F3<=((NOT L)AND(NOT M)AND N)OR(L AND M);
end f3_2;
\end{lstlisting}
\end{minipage}
\begin{minipage}{0.4\linewidth}
\begin{flushright}
\begin{tikzpicture}[x=1mm,y=1mm,line width=0.8pt,scale=0.9,framed]
%\draw[help lines] (0,0) grid (50,50);
% BOX
\draw (20,2.5) rectangle (40,22.5) node[midway]{my\_ckt\_f3};
% INPUTS
\small
\node (b) at (20,25) {}; % this is to extend the pink area
\node (a) at (20,-2.5) {}; % this is the reference point
\draw [latex-] ($(a)+(0,20)$) -- ++(-10,0) node[left]{L};
\draw [latex-] ($(a)+(0,15)$) -- ++(-10,0) node[left]{M};
\draw [latex-] ($(a)+(0,10)$) -- ++(-10,0) node[left]{N};
% OUTPUTS
\draw [-latex] ($(a)+(20,15)$) -- ++(10,0) node[right]{F3};
\end{tikzpicture}
\end{flushright}
\end{minipage}
This example shows a one-line implementation of the given logic equation.
An alternative solution to Example~2 is provided in Listing~\ref{example_2_bis}. This example represents an important concept in VHDL. The solution shown in Listing~\ref{example_2_bis} uses some special statements in order to implement the circuit. These special statements are used to provide what is often referred to as intermediate results. This approach is equivalent to declaring extra variables in an algorithmic programming language to be used for storing intermediate results. The need for intermediate results is accompanied by the declaration of extra signal values, which are often referred to as intermediate signals. Note in Listing~\ref{example_2_bis} that the declaration of intermediate signals is similar to the port declarations appearing in the entity declaration, except that the mode specification (\texttt{in}, \texttt{out} or \texttt{inout}) is missing.
The intermediate signals must be declared within the body of the architecture because they have no link to the outside world and thus do not appear in the entity declaration. Note that the intermediate signals are declared in the architecture body but appear before the \texttt{begin} statement.
\begin{lstlisting}[float, label=example_2_bis, caption=Alternative solution of Example~2.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_ckt_f3 is
port ( L,M,N : in std_logic;
F3 : out std_logic);
end my_ckt_f3;
-- architecture
architecture f3_1 of my_ckt_f3 is
signal A1, A2 : std_logic; -- intermediate signals
begin
A1 <= ((NOT L) AND (NOT M) AND N);
A2 <= L AND M;
F3 <= A1 OR A2;
end f3_1;
\end{lstlisting}
Despite the fact that the architectures \texttt{f3\_2 }and \texttt{f3\_1} of Listing~\ref{example_2} and Listing~\ref{example_2_bis} appear different, they are functionally equivalent. This is because all the statements are concurrent signal assignment statements. Even though the \texttt{f3\_1} architecture contains three CSAs, they are functionally equivalent to the CSA in \texttt{f3\_2} because each of the three statements is effectively executed concurrently.
Although the approach of using intermediate signals is not mandatory for this example, their use brings up some good points. First, the use of intermediate signals is the norm for most VHDL models. The use of intermediate signals was optional in Listing~\ref{example_2_bis} due to the fact that the example was modeling a relatively simple circuit. As circuits become more complex, there are many occasions in which intermediate signals must be used. Secondly, intermediate signals are something of a tool that you will often need to use in your VHDL models. The idea here is that you are trying to describe a digital circuit using a textual description language: you will often need to use intermediate signals in order to accomplish your goal of modeling the circuit. The use of intermediate signals allows you to more easily model digital circuits but does not make the generated hardware more complicated. The tendency in using VHDL is to think that since there is more text written on your page, the circuit you are describing and/or the resulting hardware is larger or more complex. This is simply not true. The main theme of VHDL is that you should use the VHDL tools at your disposal in order to model your circuits in the simplest way possible. Simple circuits have a higher probability of being understood and synthesized. But most importantly, a simple VHDL model is not related to the length of the actual VHDL code.
In Example~2, the conversion of the logic function to CSAs was relatively straightforward. The ease with which these functions can be implemented into VHDL code was almost trivial. Then again, the function in Example~2 was not overly complicated. As functions become more complicated (more inputs and outputs), an equation entry approach becomes tedious. Luckily, there are a few other types of concurrent construct that can ease its implementation.
\section{Conditional Signal Assignment \texttt{when}}
Concurrent signal assignment statements, seen before, associate one target with one expression. The term conditional signal assignment is used to describe statements that have only one target but can have more than one associated expression assigned to the target. Each of the expressions is associated with a certain condition. The individual conditions are evaluated sequentially in the conditional signal assignment statement until the first condition evaluates as true. In this case, the associated expression is evaluated and assigned to the target. Only one assignment is applied per assignment statement.
The syntax of the conditional signal assignment is shown in Listing~\ref{conditional_sig_assig}. The target in this case is the name of a signal. The condition is based upon the state of some other signals in the given circuit. Note that there is only one signal assignment operator associated with the conditional signal assignment statement.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=conditional_sig_assig, caption=The syntax for the conditional signal assignment statement.]
<target> <= <expression> when <condition> else
<expression> when <condition> else
<expression>;
\end{lstlisting}
\end{minipage}
The conditional signal assignment statement is probably easiest to understand in the context of a circuit. For our first example, let us simply redo Example~2 using conditional signal assignment instead of concurrent signal assignment.
\begin{leftbar}
\noindent
\textbf{EXAMPLE 3.}
Write the VHDL code to implement the function expressed in Example~2. Use only conditional signal assignment statements in your VHDL code.
\end{leftbar}
\noindent
\textbf{SOLUTION.} The entity declaration does not change from Example~2 so the solution only needs a new architecture description. By reconsidering the same logic equation of Example~2, $F3=\overline{L} \cdot \overline{M} \cdot N+L \cdot M$, the solution to Example~3 is shown in Listing~\ref{example_3}.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=example_3, caption=Solution of Example~3.]
architecture f3_3 of my_ckt_f3 is
begin
F3 <= '1' when (L = '0' AND M = '0' AND N = '1') else
'1' when (L = '1' AND M = '1') else
'0';
end f3_3;
\end{lstlisting}
\end{minipage}
There are a couple of interesting points to note about this solution.
\begin{my_list}
\item It is not much of an improvement over the VHDL code written using concurrent signal assignment. In fact, it looks a bit less efficient in terms of the number of instructions.
\item If you look carefully at this code you will notice that there is in fact one target and a bunch of expressions and conditions. The associated expressions are the single digits surrounded by single quotes; the associated conditions follow the \texttt{when} keyword. In other words, there is only one signal assignment operator used for each conditional signal assignment statement.
\item The last expression in the signal assignment statement is the catch-all condition. If none of the conditions listed above the final expression evaluate as true, the last expression is assigned to the target.
\item The solution uses relational operators. There are actually six different relational operators available in VHDL. Two of the more common relational operators are the ``='' and ``/='' relational operators which are the ``is equal to'' and the ``is not equal to'' operators, respectively. Operators are discussed at greater length in further sections.
\end{my_list}
There are more intelligent uses of the conditional signal assignment statement. One of the classic uses is for the implementation of a multiplexer (MUX). The next example is a typical conditional signal assignment implementation of a MUX.
\begin{leftbar}
\noindent
\textbf{EXAMPLE 4.}
Write the VHDL code that implements a 4:1 MUX using a single conditional signal assignment statement. The inputs to the MUX are data inputs D3, D2, D1, D0 and a two-input control bus SEL. The single output is MX\_OUT.
\end{leftbar}
\noindent
\textbf{SOLUTION.} For this example we need to start from scratch. This of course includes the now famous black-box diagram and the associated entity statement. The VHDL portion of the solution is shown in Listing~\ref{example_4}.
\noindent
\begin{minipage}{0.69\linewidth}
\begin{lstlisting}[label=example_4, caption=Solution of Example~4.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_4t1_mux is
port(D3,D2,D1,D0 : in std_logic;
SEL : in std_logic_vector(1 downto 0);
MX_OUT : out std_logic);
end my_4t1_mux;
-- architecture
architecture mux4t1 of my_4t1_mux is
begin
MX_OUT <= D3 when (SEL = "11") else
D2 when (SEL = "10") else
D1 when (SEL = "01") else
D0 when (SEL = "00") else
'0';
end mux4t1;
\end{lstlisting}
\end{minipage}
\begin{minipage}{0.3\linewidth}
\begin{flushright}
\begin{tikzpicture}[x=1mm,y=1mm,line width=0.8pt,scale=0.9,framed]
%\draw[help lines] (0,0) grid (50,50);
% BOX
\draw (20,0) rectangle (30,25) node[above]{my\_4to1\_mux};
% INPUTS
\small
\node (b) at (20,25) {}; % this is to extend the pink area
\node (a) at (20,-2.5) {}; % this is the reference point
\draw [latex-] ($(a)+(0,25)$) -- ++(-5,0) node[left]{D3};
\draw [latex-] ($(a)+(0,20)$) -- ++(-5,0) node[left]{D2};
\draw [latex-] ($(a)+(0,15)$) -- ++(-5,0) node[left]{D1};
\draw [latex-] ($(a)+(0,10)$) -- ++(-5,0) node[left]{D0};
\draw [latex-] ($(a)+(0,5)$) -- ++(-5,0) node[left]{SEL} node[pos=0.7,above]{2} node[pos=0.6]{/};
% OUTPUTS
\draw [-latex] ($(a)+(10,15)$) -- ++(5,0) node[above, pos=1.6]{MX\_OUT};
\end{tikzpicture}
\end{flushright}
\end{minipage}
There are a couple of things to note in the solution provided in Listing~\ref{example_4}.
\begin{my_list}
\item The solution looks somewhat efficient compared to the amount of logic that would have been required if CSA statements were used. The VHDL code looks good and is pleasing to the eye, qualities required for readability.
\item The ``='' relational operator is used in conjunction with a bundle. In this case, the values on the bundle SEL are accessed using double quotes around the specified values. In other words, single quotes are used to describe values of individual signals while double quotes are used to describe values associated with multiple signals, or bundles.
\item For the sake of completeness, we have included every possible condition for the SEL signal plus a catch-all \texttt{else} statement. We could have changed the line containing '0' to D0 and removed the line associated with the SEL condition of ``00''. This would be functionally equivalent to the solution shown but would not be nearly as impressive looking. Generally speaking, you should clearly provide all the options in the code and not rely on a catch-all statement for intended signal assignment.
\end{my_list}
Remember, a conditional signal assignment is a type of concurrent statement. In this case, the conditional signal assignment statement is executed any time a change occurs in the conditional signals (the signals listed in the expressions on the right-hand side of the signal assignment operator). This is similar to the concurrent signal assignment statement where the statement is executed any time there is a change in any of the signals listed on the right-hand side of the signal assignment operator.
\begin{lstlisting}[float, label=example_4_bis, caption=Alternative solution to Example~4 accessing individual signals.]
-----------------------------------------------------------------
-- entity and architecture of 4:1 Multiplexer implemented using
-- conditional signal assignment. The conditions access the
-- individual signals of the SEL bundle in this model.
-----------------------------------------------------------------
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_4t1_mux is
port (D3,D2,D1,D0 : in std_logic;
SEL : in std_logic_vector(1 downto 0);
MX_OUT : out std_logic);
end my_4t1_mux;
-- architecture
architecture mux4t1 of my_4t1_mux is
begin
MX_OUT <= D3 when (SEL(1) = '1' and SEL(0) ='1') else
D2 when (SEL(1) = '1' and SEL(0) ='0') else
D1 when (SEL(1) = '0' and SEL(0) ='1') else
D0 when (SEL(1) = '0' and SEL(0) ='0') else
'0';
end mux4t1;
\end{lstlisting}
Though it is still early in the VHDL learning game, you have been exposed to a lot of concepts and syntax. The conditional signal assignment is maybe a bit less intuitive than the concurrent signal assignment. There is however an alternative way to make sense of it. If you think about it, the conditional signal assignment statement is similar in function to the \texttt{if-else }constructs in algorithmic programming languages. We will touch more upon this relationship once we start talking about sequential statements.
The concept of working with bundles is very important in VHDL. Generally speaking, if you can use a bundle as opposed to individual signals, you should. You will often need to access individual signals within a bundle. When this is the case, a special syntax is used (e.g. \texttt{SEL(1)}). Note that the code shown in Listing~\ref{example_4_bis} is equivalent to but probably not as clear as the code shown in Listing~\ref{example_4}. Be sure to note the similarities and differences.
\section{Selected Signal Assignment \texttt{with select}}
Selected signal assignment statements are the third type of signal assignment that we will examine. As with conditional signal assignment statements, selected signal assignment statements only have one assignment operator. Selected signal assignment statements differ from conditional assignment statements in that assignments are based upon the evaluation of one expression. The syntax for the selected signal assignment statement is shown in Listing~\ref{sel_sig_assig}.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=sel_sig_assig, caption=Syntax for the selected signal assignment statement.]
with <choose_expression> select
target <= <expression> when <choices>,
<expression> when <choices>;
\end{lstlisting}
\end{minipage}
\begin{leftbar}
\noindent
\textbf{EXAMPLE 5.}
Write VHDL code to implement the function expressed by the following logic equation: $F3=\overline{L} \cdot \overline{M} \cdot N+L \cdot M$. Use only selected signal assignment statements in your VHDL code.
\end{leftbar}
\noindent
\textbf{SOLUTION.} This is yet another version of the \texttt{my\_ckt\_f3} example that first appeared in Example~2. The solution is shown in Listing~\ref{example_5}.
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=example_5, caption=Solution of Example~5.]
-- yet another solution to the previous example
architecture f3_4 of my_ckt_f3 is
begin
with ((L ='0' and M ='0' and N ='1') or (L ='1' and M ='1')) select
F3 <= '1' when '1',
'0' when '0',
'0' when others;
end f3_4;
\end{lstlisting}
\end{minipage}
One thing to notice about the solution shown in Listing~\ref{example_5} is the use of the \texttt{when others} clause as the final entry in the selected signal assignment statement. In reality, the middle clause \texttt{'0' when '0'} could be removed from the solution without changing the meaning of the statement. In general, it is considered good VHDL programming practice to include all the expected cases in the selected signal assignment statement followed by the \texttt{when others} clause.
\begin{leftbar}
\noindent
\textbf{EXAMPLE 6.}
Write the VHDL code that implements a 4:1 MUX using a single selected signal assignment statement. The inputs to the MUX are data inputs D3, D2, D1, D0 and a two-input control bus SEL. The single output is MX\_OUT.
\end{leftbar}
\noindent
\textbf{SOLUTION.} This is a repeat of Example~4 except that a selected signal assignment operator is used instead of a conditional signal assignment operator. The solution of Example~6 is shown in Listing~\ref{example_6}. The black-box diagram for this example is the same as before and is not repeated here.
\begin{lstlisting}[float, label=example_6, caption=Solution of Example~6.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_4t1_mux is
port (D3,D2,D1,D0 : in std_logic;
SEL : in std_logic_vector(1 downto 0);
MX_OUT : out std_logic);
end my_4t1_mux;
-- architecture
architecture mux4t1_2 of my_4t1_mux is
begin
with SEL select
MX_OUT <= D3 when "11",
D2 when "10",
D1 when "01",
D0 when "00",
'0' when others;
end mux4t1_2;
\end{lstlisting}
Once again, there are a few things of interest in the solution for Example~6 which are listed below.
\begin{my_list}
\item The VHDL code has several similarities to the solution of Example~5. The general appearance is the same. Both solutions are also much more pleasing to the eye than the one where the MUX was modeled using only concurrent signal assignment statements.
\item A \texttt{when others} clause is used again. In the case of Example~6, the output is assigned the constant value of \texttt{'0'} when the other listed conditions of the \textit{chooser\_expression} are not met.
\item The circuit used in this example was a 4:1 MUX. In this case, each of the conditions of the \textit{chooser\_expression} is accounted for in the body of the selected signal assignment statement. However, this is not a requirement. The only requirement here is that the line containing the \texttt{when others} keywords appears in the final line of the statement.
\end{my_list}
\begin{leftbar}
\noindent
\textbf{EXAMPLE 7.} Write the VHDL code that implements the following circuit. The circuit contains an input bundle of four signals and an output bundle of three signals. The input bundle, D\_IN, represents a 4-bit binary number. The output bundle, SZ\_OUT, is used to indicate the magnitude of the 4-bit binary input number. The relationship between the input and output is shown in the table below. Use a selected signal assignment statement in the solution.
\centering\vspace{5pt}
\begin{tabular}{c*{2}{c}r}
range of D\_IN & SZ\_OUT \\
\hline
0000 $\rightarrow$ 0011 & 100 \\
0100 $\rightarrow$ 1001 & 010 \\
1010 $\rightarrow$ 1111 & 001 \\
unknown value & 000 \\
\end{tabular}
\end{leftbar}
\noindent
\textbf{SOLUTION.} This is an example of a generic decoder-type circuit. The solution to Example~7 is shown in Listing~\ref{example_7}.
\noindent
\begin{minipage}{0.99\linewidth}
\centering
\begin{tikzpicture}[x=1mm,y=1mm,line width=0.8pt,scale=0.9,framed]
% BOX
\draw (20,8) rectangle (35,17) node[above]{my\_sz\_ckt};
% INPUTS
\small
\node (b) at (20,25) {}; % this is to extend the pink area
\node (a) at (20,-2.5) {}; % this is the reference point
\draw [latex-] ($(a)+(0,15)$) -- ++(-10,0) node[left]{D\_IN} node[pos=0.7,above]{4} node[pos=0.6]{/};
% OUTPUTS
\draw [-latex] ($(a)+(15,15)$) -- ++(10,0) node[right]{SZ\_OUT} node[pos=0.7,above]{3} node[pos=0.5]{/};
\end{tikzpicture}
\end{minipage}
\noindent
\begin{minipage}{0.99\linewidth}
\begin{lstlisting}[label=example_7, caption=Solution of Example~7.]
-------------------------------------------------------------
-- A decoder-type circuit using selected signal assignment --
-------------------------------------------------------------
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_sz_ckt is
port ( D_IN : in std_logic_vector(3 downto 0);
SZ_OUT : out std_logic_vector(2 downto 0));
end my_sz_ckt;
-- architecture
architecture spec_dec of my_sz_ckt is
begin
with D_IN select
SZ_OUT <= "100" when "0000"|"0001"|"0010"|"0011",
"010" when "0100"|"0101"|"0110"|"0111"|"1000"|"1001",
"001" when "1010"|"1011"|"1100"|"1101"|"1110"|"1111",
"000" when others;
end spec_dec;
\end{lstlisting}
\end{minipage}
The only comment for the solution of Example~7 is that the vertical bar is used as a selection character in the choices section of the selected signal assignment statement. This increases the readability of the code as do the similar constructs in algorithmic programming languages.
Once again, the selected signal assignment statement is one form of a concurrent statement. This is verified by the fact that there is only one signal assignment statement in the body of the selected signal assignment statement. The selected signal assignment statement is evaluated each time there is a change in the \textit{chooser\_expression} listed in the first line of the selected signal assignment statement. Re-evaluation also occurs every time there is a change in a conditional signal on the right-hand side of the signal assignment operator.
The final comment regarding the selected signal assignment is similar to the final comment regarding conditional signal assignment. You should recognize the general form of the selected signal assignment statement as being similar to the \textit{switch} statements in algorithmic programming languages such as C and Java. Once again, this relationship is examined in much more depth once we are ready to talk about sequential statements.
\begin{leftbar}
\noindent
\textbf{EXAMPLE 8.}
Write VHDL code to implement the function expressed by the following logic equation: $F3=\overline{L} \cdot \overline{M} \cdot N+L \cdot M$.
\end{leftbar}
\noindent
\textbf{SOLUTION.} This is the same problem examined before. The problem with the previous solutions to this example is that they required the user to somehow reduce the function before it was implemented. In this modern day of digital circuit design, you score the most points when you allow the VHDL synthesizer to do the work for you. The solution to this example hopefully absolves you from ever again having to use a Karnaugh map, or God forbid, boolean algebra, to reduce a function. The equivalent expression for $F3(L,M,N)=\overline{L} \cdot \overline{M} \cdot N+L \cdot M$ and its Karnaugh map is shown below. The solution of Example~8 is shown in Listing~\ref{example_8}.\\
\vspace{5pt}
\noindent
\begin{minipage}[t]{0.5\textwidth}
$ F3(L,M,N) = \displaystyle\sum(1,6,7) $
\end{minipage}
\begin{minipage}[t]{0.47\textwidth}
\scriptsize\textsf{\begin{tabular}{c|c|c|c}
\texttt\textbf{L} & \texttt\textbf{M}& \texttt\textbf{N}& \texttt\textbf{F3}\\
\hline
\rowcolor{light-gray} 0 & 0 & 0 & 0 \\
\hline
0 & 0 & 1 & 1 \\
\hline
\rowcolor{light-gray} 0 & 1 & 0 & 0 \\
\hline
0 & 1 & 1 & 0 \\
\hline
\rowcolor{light-gray} 1 & 0 & 0 & 0 \\
\hline
1 & 0 & 1 & 0 \\
\hline
\rowcolor{light-gray} 1 & 1 & 0 & 1 \\
\hline
1 & 1 & 1 & 1 \\
\hline
\end{tabular}}
\end{minipage}
\begin{lstlisting}[float, label=example_8, caption=Solution of Example~8.]
-- library declaration
library IEEE;
use IEEE.std_logic_1164.all;
-- entity
entity my_ckt_f3 is
port ( L,M,N : in std_logic;
F3 : out std_logic);
end my_ckt_f3;
-- architecture
architecture f3_8 of my_ckt_f3 is
signal t_sig : std_logic_vector(2 downto 0); -- local bundle
begin
t_sig <= (L & M & N); -- concatenation operator
with (t_sig) select
F3 <= '1' when "001" | "110" | "111",
'0' when others;
end f3_8;
\end{lstlisting}
\section{Process Statement}
The process statement is the final signal assignment type we will look at. Before we do that, however, we need to take a few steps back and explore a few other VHDL principles and definitions that we have excluded up to now. Remember, there are a thousand ways to learn things. This is especially true when learning programming languages, where there are usually many different and varied solutions to the same problem. This is highlighted by the many different and varied approaches that appear in VHDL books and by the many tutorials.
So, now is not the time to learn about the process statement. We will do that right after we pick up a few more VHDL concepts. Now just remember that the process statement is a statement which contains a certain number of instructions that, when the process statement is executed, are executed sequentially. In other words, the process statement is a tool that you can use any time you want to execute a certain number of instructions in a sequential manner (one instruction after the other, from top to bottom). Do not forget, however, that the process statement in itself is a concurrent statement and therefore will be executed together with the other concurrent statements in the body of the architecture where it sits.
\section{Summary}
\begin{my_list}
\item The entity/architecture pair is the interface description and behavior description of how a digital circuit operates.
\item The main design consideration in VHDL modeling supports the fact that digital circuits operate in parallel. In other words, the various design units in a digital design process and store information independently of each other. This is the major difference between VHDL and higher-level computer programming languages.
\item The major signal assignment types in VHDL are: concurrent signal assignment, conditional signal assignment, selected signal assignment and process statements. Each concurrent statement is interpreted as acting in parallel (concurrently) to other concurrent statements.
\item The process statement is a concurrent statement that contains a series of statements which will be executed in a sequential manner, one after the other. A programmer uses a process statement when he wants to execute some commands in a sequential manner.
\item The architecture body can contain any or all of the mentioned concurrent statements.
\item Signals that are declared as outputs in the entity declaration cannot appear on the right-hand side of a signal assignment operator. This characteristic is prevented from being a problem by the declaration and use of intermediate signals. Intermediate signals are similar to signals declared in entities except that they contain no mode specifier. Intermediate signals are declared \textbf{inside} the architecture body just \textbf{before} the begin statement.
\item Generally speaking, there are multiple approaches in modeling any given digital circuit. In other words, various types of concurrent statements can be used to describe the same circuit. The designer should strive for clarity in digital modeling and allow the VHDL synthesizer to sort out the details.
\end{my_list}
\section{Exercises}
\begin{my_num_list}
\item For the following function descriptions, write VHDL models that implement these functions using concurrent signal assignment.
a) $F(A,B) =\overline{A}B +A +A\overline{B}$
b) $F(A,B,C,D) =\overline{A}C\overline{D} +\overline{B}C +BC\overline{D}$
c) $F(A,B,C,D) =(\overline{A}+B)\cdot(\overline{B}+C+\overline{D})\cdot(\overline{A}+D)$
d) $F(A,B,C,D) = \displaystyle\prod(3,2) $
e) $F(A,B,C) = \displaystyle\prod(5,1,4,3) $
f) $F(A,B,C,D) = \displaystyle\sum(1,2) $
\item For the following function descriptions, write VHDL models that implement these functions using both conditional and selected signal assignment.
a) $F(A,B,C,D) =\overline{A}C\overline{D} +\overline{B}C +BC\overline{D}$
b) $F(A,B,C,D) =(\overline{A}+B)\cdot(\overline{B}+C+\overline{D})\cdot(\overline{A}+D)$
c) $F(A,B,C,D) = \displaystyle\prod(3,2) $
d) $F(A,B,C,D) = \displaystyle\sum(1,2) $
\item Provide a VHDL model of an 8-input AND gate using concurrent, conditional and selected signal assignment.
\item Provide a VHDL model of an 8-input OR gate using concurrent, conditional and selected signal assignment.
\item Provide a VHDL model of an 8:1 MUX using conditional signal assignment and selected signal assignment.
\item Provide a VHDL model of a 3:8 decoder using conditional signal assignment and selected signal assignment; consider the decoder’s outputs to be active-high.
\item Provide a VHDL model of a 3:8 decoder using conditional signal assignment and selected signal assignment; consider the decoder’s outputs to be active-low.
\end{my_num_list}