UE719
UE719
UE719
Embedded Systems
Lamri NEHAOUA
October 1, 2021
CONTENTS
I COURSE
1 DESIGN METHODOLOGY 3
1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Processor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2 Semiconductor market . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2 Wired logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.3 Programmable logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.3.1 FPGA Market . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.3.2 ASIC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.3.3 IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4 HDL design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4.1 Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4.2 Design flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2 VHDL 26
2.1 HDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2 HDL Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2.1 Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.2.2 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2.3 Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2.4 Concurrence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.3 Description styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.1 Behavioral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3.2 Dataflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3.3 Structural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.4 Data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.4.1 Objects and types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.5 New types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.5.1 Syntaxe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.5.2 Qualification of type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.5.3 Subtype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.5.4 Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.6 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.6.1 Constrained array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.6.2 Unconstrained array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.6.3 Aggregates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.6.4 Array attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.7 Code reuse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.7.1 package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.7.2 Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.7.3 Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
II TUTORIALS
1 TUTORIALS 42
1.1 Tutorial 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.1.1 Multiplexer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.1.2 Half-adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
ii
CONTENTS 1
1.1.3 Full-adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.1.4 4-bit adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.1.5 Homework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.1.6 Another 4-bit adder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.1.7 Seven-Segment Display . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.2 Tutorial 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.2.1 RS Latch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.2.2 D flip-flop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.2.3 Shift register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.2.4 BCD counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
1.2.5 PWM signal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
1.3 Tutorial 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.3.1 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.3.2 Type attributs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.3.3 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Part I
COURSE
1
DESIGN METHODOLOGY
1.1 I N T RO D U C T I O N
Digital systems are ubiquitous in our everyday life. A digital system processes information in binary
form. However, the information coming from the environment is in general in analog form. Sampling
and quantification methods allows to make this information usable by different processors. In the
literature, there are two major classifications for digital systems:
1. General Purpose Systems: combination of hardware and software for public/private use.
2. Embedded systems: generally implemented into an another system where the name of embedded.
They are designed to perform specific functions.
According to figure 1, the hardware part of a digital system can be broken down into two main parts:
processor and peripherals. The processor manages the processing of information, while the peripherals
allow interaction with the outside world via the various inputs and outputs or, to provide the processor
with additional capacities to accomplish its task via the memory blocks and co-processors. On the
other hand, the software part is also important. The software part includes all the tools necessary
for application development: programming languages, compilers, debugging tools, emulators, and
operating system.
Unlike general-purpose systems, an embedded systems system must meet more constraints as time
scheduling. Therefore, functions and tasks are handled by a specific operating system designed around
a real-time kernel, RTOS and, in this case, the system is said to be real-time.
3
1.1 I N T R O D U C T I O N 4
1.1.1 Processor
A term processor is a generic name of a processing unit whose purpose is to process the input
information in a sequential manner by a succession of simple operations and instructions. There are
two main types of processors: general purpose and special purpose. general purpose processors can
be programmed and are therefore very versatile. The memory associated with the processor contains a
series of instructions to be executed at each clock cycle. This type of processor is often referred to by
the name CPU, Central Processing Unit. These processors are more suitable for applications without
constraints of resources, memory, or autonomy. On the other hand, specific use processors are CPU to
which, additional components are added for a specific application such as signal or image processing
(figure 2 ).
Figure 2: The simplest model of a digital system. A CPU for processing data, memory for storing data and/or
instructions, and a set of I/O ports.
An example of special purpose processors are DSP, Digital Signal Processor, FPGA, Field-
Programmable Gate Array, ASIC, Application-Specific Integrated Circuit, etc. More recently, and to
meet more and more constraints of integration and complexity, the use of SoC, System on-Chip, has
become a standard in the design of digital systems . Figure 3 shows the motherboard of a Samsung
Galaxy S8 smartphone and figure 4 shows a Qualcomm Snapdragon 835 SoC chip developed by
Samsung for these smartphones. It should be noted that to implement a given function, a general
purpose processor uses more resources than a specific purpose processor because the latter uses
tailor-made logic.
Figure 4: SoC Qualcomm Snapdragon 835: more than 3 billion transistors. It contains a GPU, DSP, modem
LTE, audio codec, camera ISP and a CPU Qualcomm Kryo 280 (8 cores, 4 x 2.45 GHz with 2MB
cache L2 + 4 x 1.9 GHz with 1MB cache L2).
A CPU can be broken down into two main parts: the datapath and the control unit. The datapath
includes registers and functional units, such as ALU, Arithmetic and Logic Unit, as well as several
multiplexers for transferring and manipulating data. Figure 5 represents the basic datapath of a
microcontroller of the AVR family. The datapath receives data, performs calculations, and produces
results. It also receives signals from the control unit indicating the operations to be carried out and the
blocks to be activated. The datapath transmits status signals (status) to the control unit, indicating the
status of the operations performed.
1.1 I N T R O D U C T I O N 6
Figure 6: And what about the µC? A µC combines CPU, ROM, RAM, and I/O ports on the same chip. Other
components can also be integrated: timers, ADC, communication interfaces, etc.
The global semiconductor market will be 655.6 B$ in 2025 compared to 342.7 B$ in 2015 with a
CAGR of 6.7% (Compound Annual Growth Rate).
While the overall semiconductor market growth will be lower than in the past, several areas will
experience significantly higher growth than the overall semiconductor market. For example, the
semiconductor and sensor markets for IoT, Internet of Things, are expected to reach 114.2 B$ in 2025,
up from 27.6B$ in 2015, with a CAGR of 15.3%. Major semiconductors in IoT applications include
controllers, wireless connectivity, and built-in non-volatile memory. Also, the IoT market consists of
many segments, including commerce, automotive, medical, logistics and home automation, which
1.1 I N T R O D U C T I O N 8
have high growth potential, but with the need for very low power consumption energy for mobile
devices.
Nonetheless, the semiconductor industry’s margins are under pressure. For example, companies
that produced three to five 65nm chips per year could effectively use their operations teams. However,
the move to 40nm and below has dramatically changed the economics model. A 28nm tape-out 1 takes
78% of design time in addition and 40 % non-recurring investments 2 more than a 40nm tape-out.
Despite these issues, progress is being made whether with tools, methodologies or platform
approaches that rely heavily on reuse. While projections show that it will cost up to 300 B$ to develop
new SoCs (figure 9), the actual costs are generally much lower, provided that there are a lot of reusable
IP products.
Figure 9: Development cost. The design costs of integrated circuits have gone from 51.3 M$ for 28nm chip to
297.8 m$ for 7nm and 542.2 M$ 5nm chip.
1 In electronic design, tape-out is the end result of the design process of integrated circuits before they are sent for manufacture.
2 Refers to the one-time costs of research, design, development and test of a new product, Wikipedia.
1.2 W I R E D L O G I C 9
The development of digital systems through wired logic was widely used until the mid-1980s. Wired
logic allows a wide assortment of integrated circuits (IC) to be connected, each containing only a few
logic gates, performing a single logic function. This solution results in fixed digital systems without
any possible evolution or flexibility in the design. An example of the most basic logic gate is the NOT
gate, shown in figure 10.
Among the most widely used IC are those of the 74 series. Figure 11 shows the integrated circuit
7404, which includes six NOT gates, in the form of a DIP package, dual-inline package. For each
circuit in the 7400 series, several variants are built with different technologies. The 74LS00 variant
is built using TTL, transistor-transistor level technology, while the 74HC00 variant is built using
CMOS, complementary metal oxide semiconductor.
Figure 11: 7404 IC: two pins are used to connect to VDD and Gnd. The other pins provide a connection to the
NOT gates.
Figure 12 shows an example of wiring three logic IC to implement the function f = x1 x2 + x̄2 x3 .
1.3 P R O G R A M M A B L E L O G I C 10
Figure 12: Example of a wired logic circuit: fonction f = x1 x2 + x̄2 x3 is implemented by using 3 IC, 7404,
7408 and 7432.
1.3 P RO G R A M M A B L E L O G I C
The function provided by each of the 7400 series circuits is fixed and cannot be adapted to all possible
design situations. In addition, each circuit contains only a few logic gates, making these circuits
inefficient for the realization of large digital systems. It was necessary to manufacture circuits with a
high density of logic gates having a more flexible structure. These new circuits were introduced in the
1970s and are called PLD, programmable logic devices. Therefore, a PLD is a generic name of the
programmable devices used in the realization of logic circuits. A PLD contains a collection of logic
gate elements and programmable switches that can be customized in different ways.
Programmable logic
SPLD CPLD FPGA
PLA PLD PAL GAL
combinational combinational PLA micro-cell complex GAL LUT
sequential 1 plan
PROM PROM PROM EEPROM EEPROM DRAM/SRAM
Several types of PLD are commercially available as shown in table 1. The first PLD marketed was
the PLA, Programmable Logic Arrays, introduced in the 1970s. The general structure of a PLA is
illustrated in figure 13. The basic idea comes from the fact that logical functions can be realized as a
sum of products. PLAs are networks of unassigned gates, traversing a plane of AND gates which in
turn feeds a set of OR gates. The configuration of the networks is determined by programming each
interconnection. So the PLA inputs, namely, x1 , · · · , xn go through a set of buffer, which provide
both the value xi and its complement x̄i , to a circuit block called AND plane. The latter produces a
set of product terms P1 , · · · , Pk where each of these terms can be configured to implement a AND
1.3 P R O G R A M M A B L E L O G I C 11
function of x1 , · · · , xn . The product terms serve as inputs to a OR plan, which produces the outputs
f 1 , · · · , f m . Each output can be configured to achieve any sum of P1 , cdots, Pk .
Figure 13: PLA: programmable logic array where each point of intersection is built by a fuse. The AND
and OR plans are programmable where unwanted connections can be removed by blowing the
corresponding fuses. Some versions of PROM-based PLA are programmed by ultraviolet exposure.
The first output is: f 1 = x1 x2 + x1 x̄3 + x̄1 x̄2 x3 + x1 x3 .
Historically, programmable switches (fuses) presented two difficulties for manufacturers: they were
difficult to manufacture correctly and reduced the speed performance of the implemented circuit.
These drawbacks led, towards the end of the 1970s, to the development of a similar circuit in which
the AND plane is programmable, but the OR plane is fixed, as shown in figure 14. Such a circuit is
called PAL, Programmable Array Logic.
Figure 14: PAL: programmable array logic. Outputs are: f 1 = x1 x2 x̄3 + x̄1 x2 x3 and f 2 = x̄1 x̄2 + x1 x2 x3 .
Usually, a PAL can be programmed electrically only once and then the PROM can no longer be
programmed.
1.3 P R O G R A M M A B L E L O G I C 12
In many PALs, additional circuitry has been added to the output of each OR gate in order to provide
additional flexibility (figure 15). The OR gate combined with the extra circuit is often referred to as
macro-cell.
The GAL, Generic Array Logic, introduced in the early 80’s. Unlike PAL and PLA which use
PROM memories, programmable only once, the GAL uses EEPROM. Figure 16 shows a GAL22V10
with 10 OLMCs with AND planes of varying sizes. For example, the two OLMCs associated with
pins 14 and 23 have an AND plan of 8 terms. Each of the macro-cells has two main functional
modes: combinatorial and register (figure 17). The mode is selected by the select inputs of the 4-input
multiplexer. The latter also allows to define the logical polarity of the output signal at the pin level as
being active high or active low. In combinatorial mode, the pin associated with an OLMC is driven by
the output of the OR gate. The tri-state gate allows a pin to be defined as dynamic input, output, or
I/O. In register mode, the output pin associated with an OLMC is controlled by the Q output of the D
flip-flop.
PLAs and PALs are useful for implementing a wide variety of small digital circuits. These circuits
are limited to fairly modest sizes, generally supporting a combined number of inputs/outputs not
exceeding 32. For the implementation of circuits requiring more inputs and outputs, a more dense
circuit type can be used called CPLD, Complex PLD, represented in figure 18.
Figure 18: CPLD EPM7128S MAX 7000 from Altera includes CMOS EEPROM cells, 2500 logic gates, 128
macr-ocells, 8 LAB and 100 I/O. Each LAB is formed by 16 macro-cells.
CPLDs, introduced in mid-1980s, include multiple circuit blocks in the same chip, with internal
wiring resources to connect the circuit blocks (figure 19). Each circuit block is similar to a PAL or
PLA with a programmable AND plane and each macro-cell has a fixed OR plane and a configurable
register with clock, enable, clear and preset functions.
In CPLDs, macrocells are combined into groups called LAB, Logic Array Blocks as shown in
figure 20. Several LABs are linked together by a PIA, Programmable Interconnect Array representing
a global bus powered by all dedicated inputs, I/O pins and macro-cells. To create complex logical
functions, each macro-cell can be supplemented with shareable expander product terms and
high-speed parallel expander product terms to provide up to 32 product terms per macro-cell.
1.3 P R O G R A M M A B L E L O G I C 14
The macro-cell can be individually configured for sequential or combinational logic operation.
The macro-cell consists of three functional blocks: logic array, product-term select matrix, and
programmable register (figure 21).
1.3 P R O G R A M M A B L E L O G I C 15
Logic array is used to implement combinational functions. Product-term select matrix allows
directing the product terms either as primary logic inputs (at OR and XOR gates) to implement
combinational functions, or as secondary inputs to register control functions (clear, preset and enable).
Shareable expander product terms are inverted product terms and are fed back into the logic
array (figure 22). Parallel expanders are product terms borrowed from adjacent macro-cells. The
development software automatically optimizes the allocation of product terms based on design
requirements.
Even for CPLDs, only moderately sized logic circuits can be integrated into a single chip. A simple
method to quantify the size of a circuit to be developed is by using simple logic gates. A commonly
used metric is the total number of two-input NAND gates that would be required to build the system,
this metric is often referred to as the number of equivalent gates. By using this metric, the size of a
7400 IC is simple to measure because each chip contains only single gates. For PLDs and CPLDs, the
typical metric used is that each macro-cell represents about 20 equivalent gates. Thus, a typical PAL
of 8 macro-cells can support a circuit requiring up to approximately 160 gates. A large CPLD of 500
macro-cell circuits can support a circuit requiring up to about 10 000 equivalent gates. To implement
larger circuits, one must use a FPGA, Field-Programmable Gate Array. FPGAs are very different
1.3 P R O G R A M M A B L E L O G I C 16
from PLDs and CPLDs in that they do not contain AND or OR plans but it is constructed based on the
philosophy as shown in figure 23.
Figure 23: An FPGA contains three types of resources: logic blocks arranged in a two-dimensional array, I/O
blocks for connection to pins, and programmable interconnect switches organized into horizontal
and vertical routing channels. Example, FPGA cyclone III from Altera, 15408 LE, 346 I/O, 4 PLL,
56 M9K Memory blocks, 504 Kb RAM, 56 Multiplier
A variety of FPGA products are available in the market, with different types of logic blocks. The
most commonly used logical block is LUT, lookup table. Figure 24 shows a LUT, in truth table form,
containing storage SRAM cells used to implement a small logic function. LUTs of different sizes can
be created, the size being defined by the number of inputs.
When a circuit is implemented in an FPGA, the logic blocks are programmed to perform the
necessary functions and the routing channels are programmed to establish the required interconnections
between the logic blocks. Storage cells are volatile, which means they lose their stored contents
every time the power is off. Therefore, the FPGA must be programmed each time power is applied.
Figure 25 shows an example of internal interconnection in FPGA to set up a logical function f . In this
1.3 P R O G R A M M A B L E L O G I C 17
example, 2-input LUTs are used and connected by four wire routing channels. Switches displayed in
black are disabled.
Figure 25: A preview on a small section of a programmed FPGA. The output function is f = f 1 + f 2 where
f 1 = x1 x2 and f 2 = x̄2 x3 .
For reasons internal to the various FPGA manufacturers, several terminologies exist to designate
the internal architecture of an FPGA. For Cyclone family, Altera uses the term LE, Logic Element, to
denote a basic cell including a LUT, an adder and a register. A LAB, Logic Array Block, groups 10
LE. For the Stratix family, Altera replaced the LE with ALM, Adaptive Logic Modules. An ALM
consists of two LUTs, two adders and two registers. For the Stratix family, a LAB brings together 10
ALMs. For FPGAs of the Spartan and Virtex families, Xilinx uses the term slice for a basic module
including two LUTs, two adders and two registers. A CLB, Configurable Logic Block, groups two or
four slices, depending on the FPGA family.
Figure 26 shows an example of LE for an FPGA of the Cyclone III family from Altera (Intel since
2015). The logical elements, LE, are the smallest logical units in the architecture of this family. Each
LE is composed of a LUT with four inputs allowing to implement any function of four variables,
a programmable register, a carry chain connection (for addition), a register chain connection (to
form registers of more than one bit). LEs operate in the following modes: normal and arithmetic.
The development software automatically chooses the appropriate mode. Normal mode is suitable for
general logic applications and combinatorial functions. The arithmetic mode is ideal for implementing
adders, counters, accumulators and comparators.
1.3 P R O G R A M M A B L E L O G I C 18
Figure 26: Logic element, LE, of an FPGA of the Cyclone III family.
The global FPGA market is expected to grow from 5.9 B$ in 2020 to 8.6 B$ by 2025. It is expected to
grow at a CAGR 3 of 7.6% from 2020 to 2025. This growth is fueled by the increased adoption of the
FPGA in AI applications4 , IoT5 and ADAS6 . FPGAs offer capabilities such as high compute density
and low power consumption (for low power FPGA series), making them the preferred architecture for
various applications requiring high data flow and processing. continuous data. Here are some features:
In 2019, the APAC7 region held the largest share of the global FPGA industry as this region is
home to large semiconductor companies.
FPGAs are also used in military equipment. In November 2018, Xilinx launched Kintex and
Virtex FPGAs for space and military applications. These circuits are designed to withstand harsh
environments and ensure safe and reliable operation. Also, FPGAs have been adopted as an IaaS
resource 8 . Several cloud service providers are deploying FPGAs to accelerate service-oriented tasks
such as network encryption, deep learning, web page ranking and video conversion. For example,
the Amazon.com site uses an FPGA in its virtual machine for hardware accelerations. Likewise,
Microsoft uses FPGAs in its Azure platform for Deep Neural Network assessment and search ranking
through its Bing engine. In February 2019, Google announced an investment of over 13B$ in data
centers in the United States. On the other hand, the automotive industry is increasingly using FPGAs
in the design of ADAS systems, primarily for vision processing applications that require high level
processing and fine parallelism. In November 2019, Xilinx launched the new automotive qualified
FPGAs, FinFET+, which target ADAS and self-driving cars.
From an FPGA manufacturing technology perspective, the SRAM9 segment accounted for the
largest share of the market. SRAM offers better flexibility, re-programmability, high integration and
high performance for various applications. SRAM-based FPGAs are widely adopted in military and
aerospace, telecoms, and wireless communications systems. Fuse-based FPGAs are more rugged than
SRAM-based ones, especially in radiation environments. On the other hand, a high demand is known
for FPGAs based on Flash memory. For example, in October 2019, Lattice Semiconductor launched
the CrossLinkPlus FPGA family for the on-board vision system based on the MIPI D-PHY interface10 .
Nevertheless, FPGAs based on EEPROM memory are still relevant today.
1.3.2 ASIC
ASIC, Application Specific Integrated Circuit, are designed for a single application and function the
same throughout their lifetime, and its function cannot be changed. The logic function of ASIC is
developed in the same way as in the case of FPGAs, using HDL languages such as VHDL. However,
in the case of an ASIC, the resulting circuit is permanently etched in silicon while for FPGAs, the
circuit is made by programming a certain number of configurable blocks.
Figure 30: ASIC vs. FPGA costs. ASIC costs are higher initially even for low volume due to very high NRE
costs, but the slope is flatter. However, at a certain production volume, the cost of an ASIC and an
FPGA intersect where the ASIC becomes more cost effective.
ASICs have very high one-time engineering costs (NREs), while in the case of FPGAs this cost is
almost zero. ASIC prototyping in small quantities is very expensive, but in large volumes the cost
becomes more attractive. In the case of FPGAs, the cost of the IC is quite high, so in large volumes it
becomes expensive compared to ASICs. Therefore, choosing between an FPGA and an ASIC depends
on the end product, target market, budget, and speed required. Nevertheless, it is very convenient to at
least prototype and validate the circuit using FPGAs before moving to an ASIC with very specific
requirements.
1.3.3 IP
Traditionally, the implementation of algorithms in a digital circuit has been accomplished using ASICs
or software-programmed microprocessors. These processors execute a set of instructions to perform
a calculation. The alternative approach is to use reconfigurable circuits such as the FPGA, which
1.4 H D L D E S I G N 21
is intended to bridge the gap between hardware and software approaches, achieving much higher
performance than microprocessors, while maintaining a higher level of flexibility than ASIC. However,
FPGA systems require a great deal of development and programmability, a factor that limited their
early adoption.
Thus, FPGA vendors have gradually integrated more functionalities into their programmable
circuits, by integrating in the logic resources, particular devices like DSP blocks and memory blocks
in the form of wired functions, as shown in figure 31. Also, another trend has emerged namely the
introduction of complete solutions of microprocessors in the FPGA structure, called hard processors.
Figure 31: Heterogeneous FPGA platform with general configurable resources, hard blocks and any software
IP blocks.
On the other hand, soft IP refers to Intellectual Property libraries of high level functions that can be
included in the design. These functions are generally represented using an HDL language at the RTL11
abstraction level. These software IP functions are then synthesized into a group of programmable
logic blocks and then mapped to the FPGA.
1.4.1 Methodology
Since the appearance of the first complex systems, the design approach has continued to evolve. It
involves raising the level of representation of the system as illustrated by figure 32. This approach
has gone from a full custom design (a description at the transistor level) to a cell based design (a
description at the logic gate level) then, in the form of a hardware description language. With this
logic, we look more and more at the functionality of the system without necessarily questioning its
electronic composition. Therefore, we design a system at a high level of abstraction (figure 33), and
today we talk about design at the system level itself.
Figure 33: Abstraction Levels: at each level, the characteristics of the system must be analyzed and tested in
order to optimize the digital system. We start from the basic component towards the architecture
(bottom-up methodology) or the reverse (up-bottom methodology) or in both directions.
Figure 35: Full-Adder circuit: perform the addition between two bits A, B, by taking account for the carry
input C. It gives at its outputs the addition result S and a carry output bit Cout
Figure 36: Gate and Register Transfer level for a Full-Adder circuit.
A design flow is a sequence of step procedures to design a digital circuit and implement it in a given
technology. As shown in figure 37, design begins with establishing the specifications by breaking
down the digital system into basic modules. The description of the behavior of each module can be
done by a combination of code HDL.
Then, the synthesis step is the process of generating a logic circuit from the HDL description.
CAD tools, like Quartus, generate circuit implementations from these specifications. The process
of translating, or compiling, an HDL code to a network of logic gates is part of the synthesis. The
output is a set of logical expressions describing the logical functions necessary for the realization of
the circuit (figure 37). However, regardless of the type of design used, it is impossible for a digital
systems designer to produce optimal circuits manually. Thus, one of the important tasks of synthesis
tools is to manipulate the user’s design to automatically generate an equivalent but better circuit.
1.4 H D L D E S I G N 24
Functional Simulation occurs just after the synthesis step. A circuit represented as logical expres-
sions can be simulated to verify that it will work as expected. A functional simulator, like ModelSim,
uses the logical expressions generated during synthesis, and assumes that these expressions will be
implemented with perfect gates through which signals propagate instantly. The simulator requires
the user to specify a test-bench to be applied during the simulation. The results of the simulation are
usually provided in the form of a timing diagram that the user can examine to verify that the circuit is
functioning as required.
Figure 38: Mapping of the resources available on the FPGA to achieve the functionalities described by an
HDL language. In this figure, 6 LUTs and 2 flip-flops are used to map the 11 inputs to the 2 outputs.
Physical Design comes just after the logical synthesis step. It consists of determining exactly
how to implement the circuit on a given chip. The physical design tools map a circuit specified as
logical expressions by using the FPGA available resources as shown in figure 38. They determine the
placement of specific logical elements and what wiring connections should be made between these
elements. The last step is commonly referred to as routing.
Implementation, in this step we split the list of interconnections into components available on the
target FPGA (figure 39). The implementation includes the steps of placement and routing. Placement
consists of arranging the components of the circuit in rows and columns by respecting certain time
and/or space constraints imposed by the developer. Routing consists in choosing the paths followed
by the interconnection wires between the components of the circuit. This step is also subject to
constraints, usually of time.
Timing Simulation, a very important step in the design flow. Logic gates and other logical elements
such as registers and flip-flops cannot perform their function with zero delay. When the values of
inputs of the circuit change, it takes some time before a corresponding change occurs at the output.
This is called a circuit propagation delay. Each logic element needs time to generate a valid output
1.4 H D L D E S I G N 25
signal whenever there are changes in the values of its inputs. In addition, there is a delay caused
by the signals which must propagate along the wires which connect various logic elements. The
combined effect is that real circuits exhibit delays, which significantly impact the performances. A
timing simulator evaluates the expected delays of a designed logic circuit. Its results can be used to
determine whether the generated circuit meets the timing and speed requirements imposed by the
specifications. If the requirements are not met, the designer can re-optimize the physical design by
incorporating the timing constraints.
The last step generally consists in programming the FPGA or generating the masks which will
make it possible to buildand ASIC. Figure 40 summarizes the design flow set for a digital system
using an FPGA circuit.
The acronym VHDL stands for Very high speed integrated circuit Hardware Description Language. It
is standardized by the IEEE, Institute of Electrical and Electronics Engineers. The first standard dates
back to 1987, then updates were made in 1993, 2000, 2002 and 2008.
2.1 HDL
Hardware description language, is similar to a programming language except that HDL is used to
describe a digital system rather than being execute on the digital system. Many HDL languages
are available, some are proprietary, and can only be used to implement circuits only in proprietary
technology as is the case for Altera and Xilinx. Others are supported by standardization associations
like Verilog and VHDL.
2.2.1 Entity
Entity is a black-boxed description of the system. The entity is defined by declaring its ports. Each
port is characterized by a type, and a mode.
entity entity_name is
port (liste_ports)
{Types_specifique_pour_entity}
end entity_name;
liste_ports :
(port_identifier : [mode] indication_type [:= expression])
--exemple:
entity porte_logique is
port ( x : in std_logic; y : out std_logic);
end porte_logique;
entity and_or_inv is
port ( a1, a2, b1, b2 : in bit := ’1’; y : out bit );
end and_or_inv;
26
2.2 H D L D E S C R I P T I O N 27
2.2.2 Architecture
An architecture provides the detail of the circuit declared in the entity. It has two main parts: the
declarative section and the body of the architecture. The declarative section can be used to declare
signals, new types, variables, constants, functions, components and more. The body of the architecture
represents the functional description of the system. Two descriptions are possible: concurrent and
sequential.
architecture identifier of entity_name is
{ block_declarative }
begin
{ concurrent_statement }
end identifier;
--exemple
architecture abstract of adder is
begin
sum <= a + b;
end abstract;
--exemple
architecture primitive of and is
signal and_a, a1, a2 : std_logic;
begin
and_a <= a1 and a2;
end primitive
2.2.3 Library
A librairy includes essential packages for the design of a circuit. It consists of two clauses: library
and use. Three librairies exist:
1. WORK: built-in default library. It includes the project being designed before and after compila-
tion.
2. STD: built-in. It includes the definition of logical, relational and other operators.
3. IEEE must be explicitly declared. It includes other types as the std logic and the corresponding
operations defined in the ieee.std logic 1164 package. A specific type can be defined but we
can invoke the set of types by the keyword all.
library IEEE;
use IEEE.std_logic_1164.all;
2.2.4 Concurrence
In VHDL, everything is concurrent, and hence the order of expressions within a VHDL description
does not have any importance. However, VHDL also allows to describe sequential operations via the
process mechanism. A process is evaluated at each change of signals’ state in its sensitivity list.
--syntaxe
process (signal_names | all ) is
{process_declarative_item}
begin
{sequential_statement}
end process;
--exemple
process (A, B, C, D)
begin
if (A = ’1’ and B = ’0’) nor (C = ’0’ and D = ’0’) then F <= ’1’;
2.3 D E S C R I P T I O N S T Y L E S 28
2.3.1 Behavioral
The behavioral description of a digital system is similar to programming with any procedural language
like C or Java. This description provides a high level of abstraction in describing the system’s behavior
where the process is the basic unit. We can use Boolean equations, conditional and selection tests. In
the body of a process, expressions are evaluated sequentially, unlike expressions written in the body
of the architecture, evaluated in a concurrent fashion.
architecture behavior of bloc is
signal A_B, C_D: std_logic; --internal signal declarations
begin
process (A, B, C, D, A_B, C_D)
begin
A_B <= A and not B;
C_D <= not C and not D;
F <= A_B nor C_D;
end process;
end behavioral;
--ou encore
architecture behavior of bloc is
begin
process (A, B, C, D)
begin
if (A = ’1’ and B = ’0’) nor (C = ’0’ and D = ’0’) then F <= ’1’;
else F <= ’0’;
end if;
end process;
end behavioral;
--ou encore
architecture behavior of bloc is
begin
2.3 D E S C R I P T I O N S T Y L E S 29
process (A, B, C, D)
begin
case (A and not B) nor (not C and not D) is
when ’1’ => F <= ’1’;
when ’0’ => F <= ’0’;
when others => null;
end case;
end process;
end behavioral;
Il est à noter que les assignations de valeurs aux objets signal ne sont effectuées que lorsque le
processus se termine. Si plusieurs assignations sont faites à un objet signal dans un processus, seule
la dernière sera en fait effectuée. Les expressions contenant des objets signal sont évaluées avec les
valeurs présentes lorsque le processus est lancé. Il faut donc utiliser les assignations multiples et
interdépendantes d’objets signal à l’intérieur d’un process avec beaucoup de prudence. A l’inverse,
les objets variable prennent immédiatement la valeur qui leur est assignée par une expressions. C’est
l’essence même de la description behavior qui veut se rapprocher de la programmation procédurale.
Cependant, ces variables ne sont pas synthétisables et il va falloir être très prudent lors de la synthèse
du circuit sur FPGA.
Note that assignments of values to signal objects are only made when the process ends. If more
than one assignment is made to a signal object in a process, only the last one will actually be available.
Conversely, variable objects immediately take the value assigned to them by an expression. This is
the very essence of the description behavior which wants to get closer to procedural programming.
However, these variables cannot be synthesized and it will be necessary to be very careful when
synthesizing the circuit on FPGA.
2.3.2 Dataflow
In this description, the values of signals and ports are established by concurrent assignments. We use
Boolean equations, conditional and selection tests.
architecture dataflow of bloc is
begin
--Boolean equations
F <= (A and not B) nor (not C and not D);
2.3.3 Structural
Hierarchical design using primitives named component. The description of the digital system is based
on a simple assembly of the different components that constitute it.
component my_component is
port ( port_interface_list )
end component;
port_association_list :
port_name => ( signal_name | expression | open )
1. Partitioning:
entity and_1 is
port ( i1, i2: in std_logic; o1: out std_logic);
end and_1;
architecture dataflow of and_1 is
begin
o1 <= i1 and not i2;
end dataflow;
--Top Level
library IEEE;
use IEEE.std_logic1164.all;
entity bloc is
port (A, B, C, D : in std_logic; F : out std_logic);
end bloc;
4. Declare the components in the architecture’s declarative section of the top-level entity:
2.4 D ATA T Y P E S 31
2. positional association: generic I/O are omitted to have more readability but we must respect the
order of the component’s I/O as they declared in its entity.
C1: and_1 port map (A, B, A_B);
C2: and_2 port map (C, D, C_D);
C3: or_1 port map (A_B, C_D, F);
2.4 D ATA T Y P E S
The information in VHDL is represented as objects. Three types of objects are defined: signals,
constants and variables. Each object in VHDL has a value of a particular type. The type defines the
set of values and the set of operations (figure 43).
We use the signal object to represent scalar logic signals, in the form of buses or binary numbers. A
scalar signal takes two possible values ’0’ or ’1’. An example of a 4-bit encoded bus signal is ”1001”.
Integers can also be specified in decimal without using quotes.
signal objects can be declared in the entity declaration, in the declarative section of an architecture
and in the declarative section of a package. A signal must be declared with an associated type, as
follows:
signal nom_signal : type_signal;
-- type_signal peut etre:
bit, bit_vector,
std_logic, std_logic_vector,
signed, unsigned, integer.
2.4 D ATA T Y P E S 32
The type bit and bit vector are predefined in the STD library. In reality, the bit type is just an
enumeration of two values (’0’, ’1’).
signal x: bit;
signal y: bit_vector(1 to 4);
signal z: bit_vector(7 downto 0);
Figure 44: Two possible ways to represent a bus object: little endian (downto) and big endian (to).
The std logic type was added to the VHDL standard in IEEE 1164. It offers more capability than
the bit type. To use this type, we must include the following two declarations:
library IEEE;
use IEEE.std_logic_1164.all;
In reality, the std logic type is also a enumeration of nine values allowing to consider other
electrical levels:
library ieee;
use ieee.std_logic_1164.all;
type std_ulogic is (
’U’, -- Uninitialized
’X’, -- Forcing Unknown
’0’, -- Forcing zero
’1’, -- Forcing one
’Z’, -- High Impedance
’W’, -- Weak Unknown
’L’, -- Weak zero
’H’, -- Weak one
’-’ -- Don’t care
);
2.5 N E W T Y P E S 33
It is possible to include more options in the declaration of a signal such as the delays defined during
a transaction as shown in the following listing:
--syntaxe:
signal nom_signal : type_signal;
nom_signal <= forme_signal | valeur [after expression_delai];
expression_delai :
delai | unaffected
--exemple
y <= not x after 5 ns; -- une transaction
z <= ’1’ after T_p, ’0’ after 2*T_p; -- deux transactions
-- unaffected == null
if u = 0 then
w1 <= w1 + ’1’;
w2 <= unaffected;
else
w1 := unaffected;
w2 <= ’1’;
end if;
Packages std logic signed and std logic unsigned use another package named std logic arith. This
latter define signed and unsigned types which are equivalent to the std logic vector type. The type
unsigned allows to work with unsigned numbers or Natural numbers N. The type signed allows to
consider signed number Z codded in two-complement.
Constant allows to give to an object a value wich cannot be modified. Unlike a signal, a constant
does not represent a physical resource so this object cannot be synthesized on FPGA. The purpose of
a constant is to improve the readability of the code.
--syntaxe:
constant identifier : indication_type [:= expression]
--exemples
constant nombre_octet : integer := 4;
constant nombre_bits : integer := 8 * nombre_octet;
constant e : real := 2.718281828;
constant delai : time := 3 ns;
constant size_limit : integer := 255;
Like a constant, a variable cannot also be synthesized on FPGA. They are sometimes used to hold
calculation results and for use in loops.
--syntaxe:
variable identifier : indication_type [:= expression ]
--exemples
variable index : integer := 0;
variable start, finish : time := 0 ns;
variable sum, average, largest : real;
2.5.1 Syntaxe
In some situations, it makes sense to create new types from a basic types. The new types do not affect
the synthesis of the circuit. On the other hand, they are very useful for improving and speeding up
coding. The new type can be used in port declaration of an entity or in the declarative part of an
architecture.
You can create almost any new type from the base type integer as follows:
-- syntaxe:
type identifier is type_indication;
--indication:
2.5 N E W T Y P E S 34
--exemple
type apples is range 0 to 100;
type oranges is range 0 to 100;
type day_of_month is range 0 to 31;
type set_index_range is range 21 downto 11;
variable set_index : set_index_range;
--exemple
type resistance is range 0 to 1E9
units
ohm;
kohm = 1000 ohm;
Mohm = 1000 kohm;
end units resistance;
--exemple
type alu_function is (disable, pass, add, subtract, multiply, divide);
type octal_digit is (’0’, ’1’, ’2’, ’3’, ’4’, ’5’, ’6’, ’7’);
variable alu_op : alu_function;
variable last_digit : octal_digit := ’0’;
alu_op := subtract;
last_digit := ’7’;
use work.int_types.all;
entity small_adder is
port ( a, b : in small_int; s : out small_int );
end entity small_adder;
e can apply some attribute on a type to recover some usefull informations. A qualified expression is
an expression whose type is explicitly specified. Example: shared member of an enumerations.
--Qualification syntaxe:
type_name’(expression)
--exemple de qualification
type logic_level is (unknown, low, undriven, high);
type system_state is (unknown, ready, busy);
2.5 N E W T Y P E S 35
logic_level’(unknown)
system_state’(unknown)
--exemple de qualification
subtype valid_level is logic_level range low to high;
logic_level’(high)
valid_level’(high)
2.5.3 Subtype
Useful for restricting the scope of a base type. All the operators applicable on a base type are also
applicable for a subtype. The results are of basic type and not of subtypes.
--subtype syntaxe
subtype identifier is type_base subtype_indication
--exemple
subtype small_int is integer range -128 to 127;
variable deviation : small_int;
variable adjustment : integer;
deviation := deviation + adjustment;
2.5.4 Attributes
Attributes provide useful information about the characteristics of a type or an object. VHDL includes
predefined attributes, but you can also define new ones. The predefined attributes are divided into five
classes: value, function, signal, type and range of values.
type resistance is range 0 to 1E9
units
ohm;
kohm = 1000 ohm;
Mohm = 1000 kohm;
end units resistance;
2.6 A R R AY S
An array is a set of values of the same type. The position of each element is given by an index.
In constrained array, the limits of an index are established when the array type is defined.
-- syntaxe
type identifier is array (index_ranges) of element_subtype_indication
index_ranges:
discrete_subtype_indication | simple_expression (to|downto) simple_expression
element_subtype_indication:
type_base [range simple_expression (to|downto) simple_expression]
-- Example 2: index_ranges
type controller_state is (initial, idle, active, error);
type state_counts is array (idle to error) of natural;
type state_counts is array (controller_state range idle to error) of natural;
-- Example 3:
subtype ram_address is integer range 0 to 63;
type coeff_ram_address is array (ram_address) of real;
-- Example 4:
type RAM is array (0 to 31) of integer range 0 to 255;
A definition of type array can be unconstrained, that is, of index undefined length. the bit vector and
std logic vector types are defined in this way. An object of type unconstrained array must have its
range of index types defined when it is declared.
--syntaxe
type identifier is array (type_base range <>) of element_subtype_indication
element_subtype_indication :
type_base [discrete_range]
--exemple
type int_vector is array (integer range <>) of integer;
variable int_table : int_vector(0 to 9);
2.6.3 Aggregates
Objects of type array can also be assigned using concatenation operator (&) or aggregates. By default,
the assignment is made by taking the position into account.
-- association par position
type point is array (1 to 3) of real;
2.7 C O D E R E U S E 37
-- Pas de melange
variable coeff : coeff_array := (1.6, 2.3, 2 => 1.6, others => 0.0); -- illegal
--example
count := 0;
for index in A’range(2) loop
if A(index) then count := count + 1;
end if;
end loop;
2.7.1 package
--example declaration
-- constantes and types to model a CPU:
package cpu_types is
constant word_size : positive := 16;
constant address_size : positive := 24;
subtype word is bit_vector(word_size - 1 downto 0);
subtype address is bit_vector(address_size - 1 downto 0);
type status_value is ( halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack );
2.7 C O D E R E U S E 38
entity address_decoder is
port (addr : in address;
status : in status_value;
mem_sel, int_sel, io_sel : out bit );
end entity address_decoder;
2.7.2 Procedures
A procedure is a subroutine with a list of parameters. Parameters can have modes in, out and inout. A
procedure accepts input values and returns results, but it can also modify parameters passed to it. A
procedural call is considered as a concurrent statement. Finally, the procedures can be overloaded,
that is, two procedures can have the same identifier but a list of different parameters. Procedures are
most useful for writing part of code that is used repeatedly in a VHDL description.
procedure identifier [ (parameter_interface_list) ] is
{ subprogram_declarative_part }
begin
{ sequential_statement }
end [procedure] [identifier];
begin
-- initialization
loop
mem_address_reg := prog_counter; -- fetch next instruction
read_memory; -- call procedure
instr_reg := mem_data_reg;
...
case opcode is
...
when load_mem =>
mem_address_reg := index_reg + displacement;
read_memory; -- call procedure
accumulator := mem_data_reg;
...
end case;
end loop;
end process;
parameter_interface_list :
( [constant | variable | signal] identifier {,...} :
[ mode ] subtype_indication [:= static_expression] ) { ; ... }
--exemple
procedure do_arith_op ( op : in func_code ) is
variable result : integer;
begin
case op is
when add => result := op1 + op2;
when subtract => result := op1 - op2;
end case;
dest <= result after Tpd;
Z_flag <= result = 0 after Tpd;
end procedure do_arith_op;
-- procedure call
do_arith_op (add);
2.7.3 Function
A function is a form of a generalized operator. It is a subroutine that returns a single result. A function
can accept parameters as input. These parameters cannot be changed by the function. We use a
function call in an expression.
[pure | impure] function identifier [ (parameter_interface_list) ] return type_mark is
{subprogram_declarative_item}
begin
{ sequential_statement }
end [function] [identifier] ;
TUTORIALS
1
TUTORIALS
1.1 TUTORIAL 1
1.1.1 Multiplexer
A Mux(m:1) is used to direct m inputs I to a single output O. If we have m entries, we need log2 m
selection lines S. We consider that inputs I are of type bit, write the VHDL description of the
Mux(m:1), considering the following descriptions:
1. DataFlow and conditional test,
2. DataFlow and selection test,
3. Behavior and conditional test,
4. Behavior and selection test,
1.1.2 Half-adder
The half-adder is a combinational circuit used for the arithmetic sum of two operands A and B, each
on a single bit. At the end we get the sum S and a carry C. Write the VHDL code for this circuit by
considering that all inputs and outputs are std logic.
1.1.3 Full-adder
The full-adder has 3 inputs on a single bit: A, B and and Ci , the incoming carry. It has two outputs
S the sum and Co the outgoing carry. Write the VHDL code for this circuit following a structural
description.
Write the VHDL code for the 4-bit adder a structural description.
42
1.1 T U T O R I A L 1 43
1.1.5 Homework
The previous 4-bit adder is based on the propagation of the carry between the different full-adder.
This method is known as Ripple carry. This method is not suitable for large number additions because
of carry propagation delays. A better optimized method is called look-ahead carry. You are invited to
study this method, provide a VHDL description and a suitable test-bench for the simulations.
The VHDL description of the previous 4-bit is based on a structural arrangement of four full-adders.
Each full-adder is also a interconnection of two half-adder. However, as mentioned in the course, the
FPGA Logic Bloc has a adder with carry input and output which makes possible to use the Logic Bloc
in arithmetic mode.
Write the VHDL code of a 4-bit adder using a behavioral description. Describe the RTL level and
the Post-mapping level.
Write a VHDL description for the 7-segment display decoder of the figure below. Each segments is
identified by an index from 0 to 6. Also, we consider that each a segment is active at low level.
1.2 T U T O R I A L 2 44
1.2 TUTORIAL 2
1.2.1 RS Latch
1.2.2 D flip-flop
Write a VHDL description for the n-bits shift register of the following figure:
Write a VHDL description to generate a PWM signal of 1 KHz and duty cycle of 0.2. What must be
changed in this code to set the frequency to 1 Hz and the duty cycle to 0.5. We not that the FPGA is
clocked at 50MHz.
Modify the code so that the duty cycle can be changed without reprogramming the FPGA. For this,
we use a push button and a switch. If the switch is high, each hit on the push button increases the duty
cycle by 10%. If the switch is low, each hit of the push button decreases the duty cycle by 10%.
1.3 T U T O R I A L 3 46
1.3 TUTORIAL 3
1.3.1 Types
What are the values returned by the followxing attributes ’left, ’right, ’low, ’high et ’ascending?
Consider the following statement:
type state is (off, standby, active1, active2);
1.3.3 Arrays
Create a new type named interval from the unconstrained array type whose elements are of type
time vector, indexed by positive values.
• Declare a sample1 variable of this type to save 100 elements of 20 values.
• Creat a subtype, named interval 4, representing an array of 4 elements without constraint
starting from the base type interval.
• Declare a variable sample2 using the previous subtype where each element has 10 sub-elements.
Write a ROM entity modeled at an RTL abstraction level. The ROM has an input address of type
address index, which is a 16-bit integer. The output data is of type std logic vector of 7 bits. Initialize
the content with numbers of your choice.