0% found this document useful (0 votes)
6 views14 pages

programmable-logic

The document provides an overview of programmable logic devices (PLDs), focusing on two main strategies for realizing arbitrary truth tables: sum-of-products and lookup tables (LUTs). It discusses the evolution of programmable array logic devices (PALs) and complex programmable logic devices (CPLDs) to field-programmable gate arrays (FPGAs), highlighting their flexibility and power. Additionally, it introduces firmware design using hardware description languages (HDLs) and the importance of different abstraction levels in firmware development.

Uploaded by

priyanshu800990
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views14 pages

programmable-logic

The document provides an overview of programmable logic devices (PLDs), focusing on two main strategies for realizing arbitrary truth tables: sum-of-products and lookup tables (LUTs). It discusses the evolution of programmable array logic devices (PALs) and complex programmable logic devices (CPLDs) to field-programmable gate arrays (FPGAs), highlighting their flexibility and power. Additionally, it introduces firmware design using hardware description languages (HDLs) and the importance of different abstraction levels in firmware development.

Uploaded by

priyanshu800990
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Introduction to Programmable Logic Devices

© 2015 Kael HANSON

1 Arbitrary Logic Tables A B C Minterm Maxterm P


0 0 0 Ā · B̄ · C̄ A+B+C 0
Here we briefly review two strategies used in programmable 0 0 1 Ā · B̄ · C A + B + C̄ 0
logic devices to realize arbitrary truth tables in digital hard-
0 1 0 Ā · B · C̄ A + B̄ + C 1
ware: the sum-of-products which uses explicit ANDs and
ORs, and the lookup table (LUT) method used in most mod- 0 1 1 Ā · B · C A + B̄ + C̄ 1
ern FPGAs and CPLDs. 1 0 0 A · B̄ · C̄ Ā + B + C 0
1 0 1 A · B̄ · C Ā + B + C̄ 1
1 1 0 A · B · C̄ Ā + B̄ + C 0
1.1 Sum of Products, &c.
1 1 1 A·B·C Ā + B̄ + C̄ 1
Classic programmable logic devices, PALs, GALs, and older
CPLDs, implemented logic functions using combinations Table 1: Minterms and maxterms of 3 logic variables A, B,
of ANDs and ORs. An arbitrary function of N boolean and C in a prime number truth table.
variables may be expressed as the sum (OR) of product
minterms or the product (AND) of sum maxterms, defined
below. or POS:

Minterm The minterms associated with N boolean vari-


ables, {ai } are the product terms of all possible combi- P2 = (A + B + C)(A + B + C̄)(Ā + B + C)(Ā + B̄ + C). (2)
nations of {ai } and {āi }. There are 2N distinct terms.
Perhaps an easier way to think of this is to construct It is easy to show that P̄1 = P2 using DeMorgan’s identity.
the full boolean truth table and associate a minterm The above expression for P1 can be simplified using the rules
with each row of the table, such that the product term of Boolean algebra to obtain P1 = AC + ĀB which is easier
evaluates to true. to extract directly from the truth table.
Maxterm The maxterms associated with N boolean vari-
ables, {ai } are the sum terms of all possible combina-
tions of {ai } and {āi }. There are also 2N possible com-
binations. Whereas the minterms rows evaluate to true, 1.2 Look-Up Table Implementation
the maxterm rows evaluate to false.
For example, the minterms and maxterms of 3 logic signals Another means of realizing the prime computer of Table 1
A, B, and C are shown in Table 1. The truth table output P would be to treat the 3 inputs as an address into an 8-element
expresses whether the binary number formed by the inputs look-up table and then storing either true or false in this
is prime (true) or not (false). One can easily deduce that memory table, as appropriate. This is the strategy taken by
the minterms are formed by placement of the variable or its FPGAs and more modern CPLDs. It is trivial to determine
complement depending on whether the corresponding entry the LUT elements given a truth table or boolean logic ex-
in the table is true or false, respectively. pression. For example, the CR muon pre-trigger discussed
previously took 3 inputs:
To find the boolean function P (A, B, C), pick out the rows
where P = 1 and sum the corresponding minterms, forming
T = S1 S2 S̄3 (3)
the sum-of-products, or SOP:

P1 = ĀB C̄ + ĀBC + AB̄C + ABC (1) This could be expressed in an 8-element LUT (8 = 23 where
3 is the number of inputs) with all elements zero except for
or, equivalently, pick the rows where P = 0 and multiply the element at address 6 (110 in binary) if S1 was the MSB
the corresponding maxterms, to form the product-of-sums, of the address.

1
UW-Physics PHYS623 Introduction to Programmable Logic Devices

MAX V series from Altera was introduced in 2010 on a 180


nm process, costs between $1 and $30, contains the equiva-
lent of between 32 and 1700 macrocells, and has maximum
clocking speeds of 300 MHz.
Newer (post-2010) CPLDs have moved away from the sum-
of-product logic implementation and adopt the lookup table
used in FPGAs, along with other features historically found
only on FPGAs: PLLs, memory, &c. They retain the non-
volatile flash memory, lower power, and clock speeds of the
classic CPLD.

2.2 FPGAs
The FPGA, short for field-programmable gate array, has be-
come a popular solution for digital designers in the past
two decades due to its flexibility and power. Totally re-
programmable, it is possible to purchase generic PCBs with
hard-wired on-board peripherals but in addition, expansion
headers that connect to off-board user-custom hardware, and
develop complex systems with minimal hardware develop-
ment. The programmable logic can then be configured with
Figure 1: Typical PAL internal structure. The small
firmware1 images which define the behavior of the digital
shaded dots interconnecting the rows and columns are
system.
(re-)programmable switches and allow arbitrary product
minterms to be presented to the summing OR gate at right. FPGAs, unlike CPLDs, are based on configurations defining
the logic to be implemented held in static RAM (SRAM)
rather than flash. This means that the devices must be re-
2 Programmable Logic Types configured each time they are powered on or reset due to
the volatile nature of SRAM. Despite this inconvenience,
the much higher densities and speeds which can be achived
2.1 CPLDs
with FPGAs relative to CPLDs has given them a market
edge.
Programmable array logic devices (PALs) implement the
sum-of-products using a structure shown in Figure 1. Ex-
ternal and feedback inputs are overlaid on an array of AND 2.2.1 Logic Cells
gates. Fuse links connect these inputs into the AND gates
and can be programmed open or closed. Arbitrary product The fundamental element of the FPGA is the logic element,
sums are then formed using the multiple input OR gates. or LE (Altera); configurable logic block, or CLB (Xilinx); or
The PAL may contain a number of registers on the outputs programmable logic block, or PLB (Lattice Semiconductor).
as well to implement sequential logic. They all function similarly, though differ in the details. A
schematic of the LEs found in Altera’s Cyclone IV series of
Complex Programmable Logic Devices, or CPLDs, evolved
FPGAs is shown in Figure 2.2.1.
the registered sum-of-product structures of PAL devices to
include more flexiblity, called it a macrocell, and then packed Signals from the global interconnect matrix arrive from the
many macrocells connected by an intricate network of inter- left and exit at right. Signals at top and bottom are lo-
connects into a single IC. CPLDs replaced the fuses with cal (more on this later). The Cyclone IV LE’s each con-
switches whose state is held in nonvolatile flash RAM: once tain a single 4-input (i.e.16-element) LUT and a D register.
programmed the switch states persist across power down and The LUT may be configured either as a single 16-element
reset conditions which is a nice convenience. The flash mem- LUT or a special arithmetic mode where the LUT is split
ory can be reprogrammed thousands of times. 1 Note, firmware is also often used when discussing the software im-

CPLDs are typically distinguished from the related logic de- age running on an embedded microcontroller. I normally refer to mi-
croprocessor and microcontroller instruction bitstreams as software to
vice to be taken up shortly, the field-programmable gate ar- disambiguate the various image files in cases where a soft IP micropro-
ray, in their non-volatility, relatively low cost, clock speeds, cessor core runs on an FPGA and needs its own executable image or
logic density, and power consumption. A popular CPLD, the images.

Page -2-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

Figure 2: Logic element (LE) found in Altera’s Cyclone IV series of FPGA.

into 2 8-element LUTs where in addition to the normal out- blocks. Xilinx calls these BlockRAM and each block
put which is derived from the LUT upper half there is a contains 36kbit on the newest generation “7 series” FP-
fast carry output derived from the lower half. This is use- GAs. In both cases the RAMs may be arranged in vary-
ful for implementing adders and counters. It should be noted ing word lengths. In addition to the dedicated RAM
that the carries propagate along low propagation delay paths blocks, the LUTs may also be configured for distributed
which increases the maximum speed of adders and counters. RAM in cases where small blocks or extra flexibility is
The shaded muxes allow configuration-time selection of sig- needed.
nal paths (i.e.these muxes cannot be changed dynamically
• Hardware multipliers;
by logic). The D register have a dedicated clock enable (CE)
input. Clock enables are an important technique employed • Hard processor cores - dedicated resources which im-
in FPGA designs to control clock skew. More on this later plement high-performance ARM microprocessors are of-
(see section 5.1). fered by Altera (SoC variants of the Cyclone, Arria, and
Stratix families) and Xilinx (Zynq);
The LEs are arranged, in Cyclone IV devices in groups of 16,
in LABs or logic array blocks which contain, in addition to the • Dedicated DDR physical interfaces;
LEs, local interconnect lines which offer low skew connections • Hardware multipliers (DSP slices);
to LEs within the same LAB. The LABs are then packed
in array fashion onto the die. The layout of the smallest • Digital clock management tiles (fractional-N PLLs with
member of the Cyclone IV family - the EP4CE6E22 with precision delay taps);
only 6k LEs is shown in Figure 3. • Gigabit transceivers for high-speed serial interfaces;
• PCIe hard endpoints.
2.2.2 Other Resources
2.2.3 Clock Networks
In addition to LEs, the FPGA fabric contains other special
functions of general use:
Clocks are handled differently from normal logic in FPGA de-
• Random access memory (RAM) blocks. On Altera de- signs: they are routed along low-skew networks, interconnect
vices these are arranged in 9kbit blocks called M9K freeways, while normal logic must travel the surface streets.

Page -3-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

Figure 3: Structure of Altera EP4CE6E22 6k LE Cyclone IV FPGA. Each small rectangular tile in the matrix is a logic array
block (LAB) which itself contains 16 logic elements (LEs) and local interconnects (zoom at right). The greyed-out tiles are
unused. The two light blue strips are M9K memory blocks and the light red stripe contains the DSP multiplier blocks. Two
PLLs are located in opposite corners of the die. Around the periphery are located the various I/O banks. Each I/O bank
is capable of supporting several signaling standards, however, as I/Os within each bank share the power rail, designers are
constrained to common signaling within a bank.

Page -4-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

There are only a few entry points to these preferred routes clearer after discussing the highest level of design abstrac-
where normal logic can access the clock networks. Because tion.
logic signals can accumulate a considerable delay in travelling This level is called the behavioral modeling level and is de-
these routes, it is strongly discouraged in firmware designs scribed using one or more textual-based HDLs as opposed
to connect the output of LUTs or registers to clock inputs. to graphical-based schematic capture. The designer speci-
The standard work around for instances where gated clocks fies how the logic signals are to behave and how they are
or clock dividers would normally be used is to use clock en- linked togethers but does not explicitly use gates to do so.
ables. These are described further in Section 5.1 Statements to the effect of “make a group of signals C which
are the binary sum of signals A and B” or “at the rising
edge of the clock signal set the state of a state machine to
3 Firmware Design Tutorial some specified state if the value of an input signal is high,
otherwise remain in the current state” are how the design
is expressed in behavioral modeling. To be quite honest, de-
Firmware development using a hardware description lan- signers are free to model at the gate or even technology level:
guage (HDL) offers many advantages over schematic entry, as will soon be shown, a basic modeling concept present in all
however it presents a steep learning curve. We will plunge HDLs is the module which allows encapsulation of firmware
in, tutorial fashion: after giving some high-level guidance, sub-circuits in boxes with input and output ports. It is en-
the reader is presented with familiar examples of logic gates tirely possible2 to define boolean gates or D or JK flip-flops
and shown how they are modeled in the two common HDLs as firmware modules or even use vendor-supplied modules
in the hope that firmware design patterns will be recognized that implement the primitive logic cells and connect these
and generalized. Then the important subject of simulation together in the firmware source text.
testbenches will be used to demonstrate good design prac-
tice (test early, test often) and explore additional features of In my experience, design expression at the behavioral level in
HDLs. an HDL is the most efficient method of design entry and I see
the design globally as a collection of the firmware modules.
However, within a given firmware module I always seem to
have a running guess at least of how the synthesizer will
3.1 Three Levels of Abstraction render the RTL.
Coming back briefly to the comment about behavioral mod-
There are three levels on which a firmware designer can, and
eling statements that are not synthesizable (i.e., unable to
ought to, regard the firmware design. Starting with the most
be realized in hardware), one may well guess that there are
concrete there is the technology level: at this level the de-
applications of behavioral modeling beyond firmware imple-
sign exists mapped onto the various logic elements and other
mentation. HDLs are also used for documenting and sim-
resources on the PLD. It is probably impossible to compre-
ulating digital circuits. Only a subset of the languages are
hend an entire design of even middling complexity at this
used to implement firmware and this is a particularly steeply-
level, nevertheless it is often necessary for reasons of opti-
sloped section of the learning curve for HDLs. It is not al-
mization to examine critical path elements at this low level.
ways clear which constructs will synthesize; worse, it is not
Also, in order to understand the reports generated by the
consistent across different toolchains. An intuitive under-
logic synthesis tools, resource utilization for example, some
standing of the RTL representation of the behavioral model
familiarity with the technology level is useful.
helps: if a statement would take a great number of logic
At the next level, detaching itself slightly from the reality of gates to implement, be on guard that it may not synthesize.
the underlying logic cells, the design exists on the RTL, reg- Having said that, most synthesizers will infer arbitrarily long
ister transfer level, or sometimes called gate level. A designer adders from a single line of HDL code which adds two signals.
entering the firmware design in schematic capture mode in- Now that many FPGAs have dedicated hardware multipli-
puts directly at this level. It is considerably easier to navi- ers, inference of DSP multiplier blocks is often supported by
gate a design here: hierarchical structure exists or can exist synthesis tools. Recommendation: invest time reading the
at this level so generic (i.e., counters) and user-defined com- documentation of each tool to see what it will do.
posed logic blocks are used to improve design readability.
The design, while not a literal representation of the low-level
structure, is a functionally equivalent view and, moreover, is 3.2 VHDL and Verilog
able to be realized on the PLD, unlike some constructions
VHDL (Very High Speed Integrated Circuit HDL) and Ver-
found at the higher level. This may seem an odd comment
ilog are the two most popular HDLs in use currently. These
to make: what’s the point of designing firmware that cannot
be implemented in hardware? The answer should become 2 and occassionally necessary for design optimization

Page -5-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

languages have evolved over time, again read the tool doc- lines inform the synthesizer that the IEEE code library
umentation to see what standard is supported. Despite an called std_logic_1164 must be loaded to gain access to the
admitted personal bias toward VHDL, there is not a right std_logic type. VHDL contains many built-in types however
choice nor a wrong one - each have strengths and weak- the type most used for logic synthesis, std_logic, is contained
nesses: VHDL supports some high-level constructs which in an add-on (but omnipresent) library. VHDL makes a dis-
Verilog does not but Verilog syntax is much more succint. tinction between module interface and implementation and
Verilog syntax is close to C and thus more intuitive to a so requires the designer to declare the input and output ports
wider group of people while VHDL has an Ada-like syntax in the entity declaration between lines 4 and 6, while putting
which takes some getting used to. SystemVerilog with its the implementation in an architecture block, here between
Verilog syntax and support for more abstraction is now sup- lines 8 and 11.
ported by major toolchains and so may be the right choice 1 library ieee ;
for future-looking designers. To give a flavor for both VHDL 2 use i e e e . std_logic_1164 . a l l ;
and Verilog, the basic introductory portions of this tutorial 3
4 e n t i t y my_nand i s
on HDLs will include and compare both languages. However,
5 p o r t ( a , b : i n s t d _ l o g i c ; q : out s t d _ l o g i c ) ;
the later sections will present only VHDL. 6 end e n t i t y my_nand ;
7
8 a r c h i t e c t u r e b e h a v i o r a l o f my_nand i s
3.3 Entities and Modules 9 begin
10 q <= a nand b ;
11 end a r c h i t e c t u r e b e h a v i o r a l ;
VHDL and Verilog designs are entered into text files with
extension .vhd or .vhdl for VHDL, .v for Verilog files. By
convention one file holds one design unit. The basic design
unit is the entity (VHDL) or module (Verilog). All firmware 3.4 Modeling Sequential Logic
designs start with the top module whose I/O ports then cor-
respond to the physical I/O pins of the IC. Modules are then While similar concepts exist in both languages for concur-
hierarchically arranged to arbitrary depth. rent (combinational) and sequential logic, Verilog and VHDL
differ substantially on how they handle stateful and state-
This tutorial starts with a familiar circuit element, the 2- less signals. Before tackling this more difficult topic, let’s
input NAND gate of Figure 4. first cover each language’s syntax to deal with sequential
events: Verilog’s always blocks and VHDL’s process state-
ments which are of similar nature. Again, we take a known
example from the real digital world: a JK flip-flop, Fig-
ure 5.

Figure 4: The 2-input NAND modeled in HDLs.

3.3.1 Verilog NAND

The following 3-line Verilog module implements the NAND


gate. The syntax should be pretty obvious to those familiar
with C-like languages: a module definition looks like a C Figure 5: JK flip-flop and truth table.
function definition with the input and output signals taking
the place of function arguments. Inside the module, the only
action taken is the assignment of the result of the NAND 3.4.1 Verilog JK Register
operation to the output port q.
1 module my_nand( i n p u t a , i n p u t b , output q ) ; 1 module j k f f (
2 a s s i g n q = ~( a & b ) ; 2 input wire clk ,
3 endmodule 3 input wire rst ,
4 input wire j ,
5 input wire k ,
6 output reg q
3.3.2 VHDL NAND 7 );
8 always @( posedge c l k , r s t ) begin
9 i f ( r s t == 1) begin
The equivalent code in VHDL is some four times length- 10 q <= 1 ’ b0 ;
ier and requires a bit more explanation. The first two 11 end

Page -6-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

12 e l s e begin 16 begin
13 case ({ j , k }) 17 q <= q_int ;
14 2 ’ b00 : ; 18 process ( clk , r s t )
15 2 ’ b01 : q <= 1 ’ b0 ; 19 begin
16 2 ’ b10 : q <= 1 ’ b1 ; 20 i f r s t = ’ 1 ’ then
17 2 ’ b11 : q <= ~q ; 21 q_int <= ’ 0 ’ ;
18 default : ; 22 e l s i f r i s i n g _ e d g e ( c l k ) then
19 endcase 23 case s t d _ l o g i c _ v e c t o r ’ ( j & k ) i s
20 end 24 when ”00” => n u l l ;
21 end 25 when ”01” => q_int <= ’ 0 ’ ;
22 endmodule 26 when ”10” => q_int <= ’ 1 ’ ;
27 when ”11” => q_int <= not q_int ;
28 when o t h e r s => n u l l ;
The module’s input and output ports are enumerated in lines 29 end case ;
2-6. It is more conventional to write port lists in this man- 30 end i f ;
ner, one port per line, as opposed to several per line unless 31 end p r o c e s s ;
the list fits on a single line. Note that the output port has 32 end a r c h i t e c t u r e b e h a v i o r a l ;

the reg type because it is a stateful signal. We still have


not seen explicit wire declarations, however, the inputs are
implicitly wires possibly connecting to registers elsewhere. The library and use clauses are identical to the first VHDL
An alternative to declaring q a reg in the port list would listing (these two lines begin practically every VHDL source
have been to declare a register within the module and then file). Like Verilog, it is more usual to write out port lists one
connect an output wire to it but the style presented in the port per line. Because VHDL enforces write-only access for
listing saves one line of typing. Inputs are always wires. The out ports, the port read on line 25 would cause an error on
always keyword introduces a procedural block of statements synthesis if we’d tried to read from it - so an internal signal is
which are evaluated sequentially, in order. used and the output simply connected to it. VHDL offers the
buffer type of port, however that also has some limitations
The block is triggered when one or more of the signals inside
on what can be connected to it so this simple work-around
the (), called the sensitivity list change state. The posedge
is IMO preferred in the majority of cases.
keyword on clk restricts the trigger to only the rising edge
of clk. Inside the procedural block an if-else statement de-
termines which signal triggered the block: the asynchronous VHDL process statements also include a sensitivity list but
reset or the clock edge. In case the asynch reset and clock will trigger on every signal change, therefore the edge direc-
edge both trigger simultaneously, the asynch reset wins. If tion of clk is tested on line 20. You may be tempted to model
the async reset triggers, the q output is set to logical ‘0’: the a dual edge triggered register to react at double speed. This
notation 1’b0 is the Verilog way to express a 0 bit, and 1’b1 will work in simulation. Currently, however, such dual edge
expresses a 1 bit. flip flops do not exist in FPGAs. Don’t worry, there are
other ways to achieve the same effect.
If the clock edge triggers then the else branch is selected and
the output is determined by the state of j and k. By enclosing The same trick is used here to write a compact case state-
j and k in curly braces, they get smashed together to form a 2- ment to handle the JK’s truth table: signals j and k are
element bit vector which can succinctly be compared against concatenated using the & operator on line 21. The result-
the case statement cases which echo the JK’s truth table ing bit string must be type cast to std_logic_vector type:
(Fig. 5). VHDL is a strongly typed language and requires that any
3.4.2 VHDL JK Register type ambiguities be resolved explicitly.

1 library ieee ; 3.5 Simulation Constructs


2 use i e e e . std_logic_1164 . a l l ;
3 use i e e e . numeric_std . a l l ;
4
5 entity j k f f is The preceeding listings were models of real gates, so by de-
6 port ( sign synthesizable. We now explore models that will not
7 clk : in std_logic ;
synthesize to real gates but are rather for the sole purpose
8 rst : in std_logic ;
9 j : in std_logic ; of simulating models. We will construct so-called simulation
10 k : in std_logic ; testbenches to test the functional behavior of the previous
11 q : out std_logic ); listings. This is also show how to instantiate modules, that
12 end e n t i t y jkff ;
13
is how to build circuit structure by inclusion of sub-modules
14 architecture b e h a v i o r a l of j k f f i s into containing modules. Again, both Verilog and VHDL
15 s i g n a l q_int : s t d _ l o g i c ; testbench drivers will be demonstrated.

Page -7-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

3.5.1 Verilog Testbench The JK flip-flop DUT is placed in lines 27–28. The
ports are mapped using the syntax .port_name(net), where
Testbenches are special examples of modules with no inputs port_name is the name of the port in the module definition,
and outputs – they exist only in their own isolated simula- and net is the name of the wire or register in the current
tion universes. The first line of the testbench is a directive module to connect to that port.
telling the simulator what is the fundamental time step in
the simulation. This will become important to understand
time in the # delay statements on lines 25 to 34. Otherwise 3.5.2 VHDL Testbench
the file is a normal Verilog file with the caveat that it will
not produce hardware files of course. Similar to Verilog testbenchs, VHDL testbenches are entities
with no ports. VHDL entity local signals are declared in
Module local nets and registers are declared in lines 5–6. the lines between the architecture keyword and the begin,
The parameter is a constant giving the clock period. It is here lines 8–21. The component declaration, lines 14–21,
defined here to define clock half period delays, described in is needed to declare to VHDL that there exists an entity
the very next paragraph, in one place so that, if the clock or module somewhere with those I/O ports. Note that the
period changes, it can be changed in just one place. module could be written in Verilog.
Clocks are simulated using continuously retriggered always 1 library ieee ;
2 use i e e e . std_logic_1164 . a l l ;
blocks, seen in lines 9–13. At the beginning of the block the 3
clk is set to ‘0’. Line 11 contains a delay statement, only 4 entity jkff_tb is
useful in simulation, where the number after the # spec- 5 end e n t i t y j k f f _ t b ;
ifies how many time units, specified by the ‘timescale di- 6
7 architecture simulation of j k f f _ t b i s
rective, should elapse before the statement is executed. It 8 signal clk : std_logic ;
waits one half clock period, sets the clock high, then waits 9 signal rst : std_logic ;
another half clock period on line 12 before repeating the end- 10 signal j , k : std_logic ;
less loop. 11 signal q : std_logic ;
12 constant CLKPER : time := 10 ns ;
1 ‘ t i m e s c a l e 1 ns / 1 ps 13
2 14 component j k f f i s
3 module j k f f _ t b ( ) ; 15 port (
4 parameter CLKPER = 1 0 ; 16 clk : in std_logic ;
5 reg c l k , j , k , r s t ; 17 rst : in std_logic ;
6 wire q ; 18 j : in std_logic ;
7 19 k : in std_logic ;
8 // Clock g e n e r a t o r 20 q : out std_logic );
9 always begin 21 end component j k f f ;
10 c l k = 1 ’ b0 ; 22 begin
11 #(CLKPER/2) c l k = 1 ’ b1 ; 23
12 #(CLKPER/ 2 ) ; 24 −− c l o c k g e n e r a t o r
13 end 25 clkgen : process
14 26 begin
15 // S t i m u l u s g e n e r a t o r 27 c l k <= ’ 0 ’ ;
16 i n i t i a l begin 28 wait f o r CLKPER/ 2 ;
17 { j , k} = 2 ’ b00 ; 29 c l k <= ’ 1 ’ ;
18 rst = 1 ’ b1 ; 30 wait f o r CLKPER/ 2 ;
19 #10 k = 1 ’ b1 ; 31 end p r o c e s s c l k g e n ;
20 #30 r s t = 1 ’ b0 ; 32
21 #50 j = 1 ’ b1 ; 33 s t i m u l i : process
22 #412 r s t = 1 ’ b1 ; 34 begin
23 #32 r s t = 1 ’ b0 ; 35 r s t <= ’ 0 ’ , ’ 1 ’ a f t e r 15 ns , ’ 0 ’ a f t e r 40 ns ;
24 end 36 j <= ’ 0 ’ , ’ 1 ’ a f t e r 60 ns ;
25 37 k <= ’ 0 ’ , ’ 1 ’ a f t e r 80 ns ;
26 // DUT 38 wait ;
27 j k f f jk_inst (. clk ( clk ) , . rst ( rst ) , 39 end p r o c e s s ;
28 . j ( j ) , . k(k ) , . q(q ) ) ; 40
29 endmodule 41 j k _ i n s t : j k f f p o r t map( c l k=>c l k , r s t=>r s t ,
42 j=>j , k=>k , q=>q ) ;
43
The initial block, lines 16–24, is similar to the always block 44 end a r c h i t e c t u r e s i m u l a t i o n ;
but is executed only once. It is used here to define stimuli for
the device under test (DUT). It is used in synthesizable code Lines 25–31 mirror the Verilog clock generation using VHDL
to set initial conditions for registers, memories, &c. wait statements. The stimuli are generated in another pro-

Page -8-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

cess which terminates in a wait halting the process, func- unknown, i.e. driven to different levels by multiple sources;
tionally equivalent to the Verilog initial block. Note that in ‘L’ weak pull-down; ‘H’ weak pull-up; ‘-’ don’t care.
VHDL, signal assignments happen asynchronously (they act std_logic objects can be used where bit types are
like non-blocking assignments in Verilog) so that, while rst used.
goes high at 15 ns and then back low at 55 ns, the rising edge
of j happens at 60 ns, and k at 80 ns. This is in contrast to Example signal declarations (with initial values):
the cumulative delays of Verilog delay statements. Not sur- s i g n a l c l k : b i t := ‘ 0 ’ ;
prisingly, VHDL wait statements and delayed assignments s i g n a l sda : s t d _ l o g i c := ‘H ’ ;
are not synthesizable.
Note that setting std_logic objects to anything other than
‘0’ or ‘1’ in code meant for hardware synthesis is likely to
result in the synthesizer silently (!!) ignoring the assign-
4 More on VHDL ment.

At this point we conclude the tutorial and backup to de-


scribe the VHDL language syntax only in enough detail to Integer Signed, whole numbers are modeled by the integer
understand the following sections. It’s a vast language, and type. Because logic resources are often at a premium, it is
readers interested in a full specification of the language are common, and encouraged to restrict integers to the range
referred to the bibliography, in particular the book by Ashen- needed using range constraints:
den. s i g n a l count : i n t e g e r range 0 to 2 5 5 ;

N.B.: VHDL is not case sensitive. Verilog is. The above declaration would result in allocation of only 8
flip flops instead of potentially 32. Standard VHDL defines a
4.1 Data Types natural integer subtype which only includes positive integers
and zero.
VHDL is a strongly typed language and provides many types,
each one serving a specific purpose. Data types specify the 4.1.2 Array Types
nature of signals and variables (sec. 4.3).
Standard Logic The type std_logic_vector is an array
of std_logic elements used ubiquitously to describe multibit
4.1.1 Scalar Types
logic arrays. It is common practice to order bit arrays with
MSB on the left and LSB on the right, the way numbers are
Booleans With the prior duality between digial logic and
normally written. For example, a signal group to hold the
boolean algebra, one might imagine the fundamental logic
32-bit sum of two addends could be declared like this:
type to be a boolean. A boolean type does exist, with possi-
ble values false and true, however since logic signals tend to s i g n a l sum32 : s t d _ l o g i c _ v e c t o r (31 downto 0 ) ;
come in groups of many bits, and character strings are less
std_logic_vector literals are bit strings delineated by double
bulky typograpically than boolean arrays, booleans are not
quote marks. By default the bit strings are binary base-2 but
the dominant type. Nonetheless, they are common and quite
can be written as hexadecimal base-16 by prepending an x
useful.
before the bit string:
Example signal declaration (with initial value): sum32 <= X” 4000C8B3” ;
s i g n a l t r i g g e r e d : bo ol e a n := f a l s e ;
which is equivalent to
sum32 <= X” 01000000000000001100100010110011 ” ;
Bits and Standard Logic Bit types take on (character)
values ‘0’ and ‘1’ and are easier to gang into bit vectors. Individual elements can be accessed read or write:
However, the std_logic type is normally used in preference i f sum8 ( 1 1 ) = ’ 1 ’ then
to bit types because logic synthesis tools need to model logic −− t r u e
end i f ;
states other than LO and HI: other possible states are tri-
stated (high impedance), and weak pullups or pulldowns, to
as can entire slices
name a few. To encompass models with these states, the
IEEE has developed a standard package (std_logic_1164) i f sum32 (15 downto 12) = ” 1100 ” then
−− a l s o t r u e
which defines the std_logic type. Valid std_logic values are: end i f ;
‘0’ logic LO; ‘1’ logic HI; ‘Z’ tri-stated; ‘U’ uninitialized; ‘X’

Page -9-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

Signed and Unsigned The signed and unsigned types shift operation. Division (’/’), modulus (mod), and remain-
are used for modeling numeric computations. They are der (mod) will synthesize to division and modulus logic in
bit strings, not integers, however the packages which define the Quartus synthesizer:
them, numeric_std and numeric_bit, define a number of oper-
signal w : u n s i g n e d (15 downto 0) := x ”3 f 0 a ” ;
ators which allow bitwise and arithmetic operations between signal x : u n s i g n e d (15 downto 0) := x ” 0049 ” ;
signed, unsigned, and integer types. signal y : u n s i g n e d (15 downto 0);
signal z : u n s i g n e d (31 downto 0);
constant u1 : u n s i g n e d (7 downto 0) := x ”44” ; y <= w / x;
constant u2 : u n s i g n e d (3 downto 0) := b” 1010 ” ; z <= w * x;
i f u2 < 10 then
−− not t r u e should work but will consume a fair number of logic re-
end i f ;
sources.

4.1.3 User-Defined Types 4.2.3 Shift Operators

Enumerations Enumerated data types specify a type Two directions (left, right) and three varieties (rotations, log-
which can taken on a small number of discrete values. Finite ical, arithmetic) of shift operation work on bit vectors. Here
state machine states are the textbook example of uses for is the list:
enumerated types. The type definition defines a type which
is later attached to a data object: rol Rotate bits left N places, bits which fall off the left hand
type s t a t e _ t i s ( i d l e , edge , w a i t i n g ) ;
side return to fill the rightmost bit;
s i g n a l s : s t a t e _ t := i d l e ;
ror Rotate bits right N places, new bits fill leftmost bit from
bits exiting on right;
sll Logical shift left. Bits shift N places to the left filling
4.2 Operators right bits with zeros;
4.2.1 Logical Operators srl Logical shift right. Bits shift N places to the right filling
left bits with zeros;
Taking bit or bit vector arguments of equal length and re-
sla Arithmetic shift left. Bits shift N places to the left. The
turning bit or bit vector, the following logical operators com-
rightmost bit holds its state and is propagated to the
pute the named logic operation: not, and, nand, or, nor, xor,
neighboring bits in the shift;
and xnor. Examples:
signal a : s t d _ l o g i c _ v e c t o r (3 downto 0) := ” 1010 ” ; sra Arithmetic shift right. Bits shift N places to the right.
signal b : s t d _ l o g i c _ v e c t o r (3 downto 0) := ” 0011 ” ; The leftmost bit holds its state and is propagated to the
signal c : s t d _ l o g i c _ v e c t o r (3 downto 0); neighboring bits in the shift.
signal d : s t d _ l o g i c _ v e c t o r (3 downto 0);
signal e : s t d _ l o g i c _ v e c t o r (3 downto 0);
signal f : s t d _ l o g i c _ v e c t o r (3 downto 0);
4.2.4 Comparison Operators
c <= not b ; −− result = ”1100”
d <= a xor b ; −− result = ”1101”
e <= a nor b ; −− result = ”0100” The comparison operations are equality: =; inequality: /=;
f <= b and ( c or d ) ; −− result = ”0001” less than: <; less than or equal: <=; greater than: >; greater
than or equal: >=. All return boolean.

4.2.2 Arithmetic Operators


4.2.5 Concatenation Operator
Addition and subtraction via the ’+’ and ’-’ operators works
on integer and signed and unsigned types and generally is The & operator concatenates two bit vectors:
synthesizable. It is possible with a bit of extra typing to add
and subtract std_logic_vector types (Sec. 4.4). Multiplica- s i g n a l c1 : s t d _ l o g i c _ v e c t o r (5 downto 0) := ” 101110 ” ;
s i g n a l c2 : s t d _ l o g i c _ v e c t o r (2 downto 0) := ” 010 ” ;
tion (’*’ operator) of integer and bit types often infers the s i g n a l c3 : s t d _ l o g i c _ v e c t o r (8 downto 0 ) ;
correct hardware strutures, with the special case of power-of- c3 <= c1 & c2 ; −− r e s u l t = ”101110010”
two multiplication always being OK as it is equivalent to a

Page -10-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

4.3 Signals and Variables 1 library ieee ;


2 use i e e e . std_logic_1164 . a l l ;
3
Now to address the difficult subject of VHDL signals and 4 entity clkenable is
variables. Unlike Verilog, VHDL makes no distinction be- 5 g e n e r i c (MODULUS : i n t e g e r ) ;
tween stateless connections and stateful signals: all physical 6 port ( c l k : in std_logic ;
signals are modeled as signal objects. Signals are declared in 7 ce : out s t d _ l o g i c ) ;
8 end c l k e n a b l e ;
the lines before the begin line of architecture blocks. Input 9
and output ports of entities are signals. Signals are assigned 10 architecture b e h a v i o r a l of clkenable i s
values, either literal values or the results of operations us- 11 begin
12 clken : process ( clk )
ing the signal assignment operator, <= (yes, it looks like
13 v a r i a b l e count : i n t e g e r range
less than or equal), or by attachment to ports in module 14 0 to MODULUS−1 := 0 ;
instantiations. They can be assigned within process state- 15 begin
ments but this is where it gets weird: signal assignments in 16 i f r i s i n g _ e d g e ( c l k ) then
17 ce <= ’ 0 ’ ;
processes don’t occur immediately but rather when the pro- 18 i f count = MODULUS−1 then
cess reaches the suspend state3 Sometimes this gets in the 19 count := 0 ;
way, so another data object, the VHDL variable, must be 20 ce <= ’ 1 ’ ;
used. 21 else
22 count := count + 1 ;
Variables are declared and exist only within a specific pro- 23 end i f ;
cess. If the value of the variable needs to be communicated 24 end i f ;
25 end p r o c e s s ;
outside the process, it must be assigned to a signal. Vari- 26 end b e h a v i o r a l ;
ables can take on any type a signal can. Variables do update
immediately. The variable assignment operator is :=. The
use of variables is illustrated in Section ??.
5.2 Example: CR Muon Trigger
Here is presented the firmware solution to the problem of
4.4 Standard Logic Arithmetic triggering on a muon decay in flight. The testdeck:
Frequently, it is necessary to perform arithmetic operations 1 library ieee ;
2 use i e e e . std_logic_1164 . a l l ;
on std_logic_vector types. It’s a bit bulky, however, casting 3 use i e e e . numeric_std . a l l ;
to either signed or unsigned types is the right way to do this. 4
Don’t forget to cast back to std_logic_vector: 5 e n t i t y crmu_tb i s
6 end crmu_tb ;
1 s i g n a l x , y : s t d _ l o g i c _ v e c t o r (9 downto 0 ) ; 7
2 s i g n a l z : s t d _ l o g i c _ v e c t o r (19 downto 0 ) ; 8 a r c h i t e c t u r e B e h a v i o r a l o f crmu_tb i s
3 z <= s t d _ l o g i c _ v e c t o r ( s i g n e d ( x )* s i g n e d ( y ) ) ; 9 constant CLOCK_PERIOD : time := 10 ns ;
10 signal clk : s t d _ l o g i c := ’ 0 ’ ;
11 s i g n a l pmt : s t d _ l o g i c _ v e c t o r (2 downto 0 ) ;
12 s i g n a l daq_trig : std_logic ;
13 component muon_decay_trigger i s
5 VHDL Design Patterns 14 port (
15 clk : in std_logic ;
16 s : i n s t d _ l o g i c _ v e c t o r (2 downto 0 ) ;
5.1 Clock Enable 17 trig : out s t d _ l o g i c ) ;
18 end component muon_decay_trigger ;
19 begin
Often a divided clock or gated clock is needed. Clock signals 20 clkgen : process ( clk )
are routed differently than other logic, along special low-skew 21 begin
lines, because of their critical role in synchronous circuits 22 c l k <= not c l k a f t e r CLOCK_PERIOD/ 2 ;
and timing is hard to control when mixing clocks and logic 23 end p r o c e s s c l k g e n ;
24
and is thus not recommended. Looking back to Figure 2.2.1, 25 physics : process
the register features an enable input: the edge trigger only 26 begin
functions when the CE input is high. By controlling the 27 pmt ( 0 ) <= ’ 0 ’ , ’ 1 ’ a f t e r 500 ns ,
’ 0 ’ a f t e r 700 ns ;
state of the enable, functionality equivalent to clock gating 28
29 pmt ( 1 ) <= ’ 0 ’ , ’ 1 ’ a f t e r 510 ns ,
or division can be achieved. A VHDL module to generate 30 ’ 0 ’ a f t e r 650 ns ;
clock enables is presented in the code listing below. 31 pmt ( 2 ) <= ’ 0 ’ , ’ 1 ’ a f t e r 8000 ns ,
32 ’ 0 ’ a f t e r 8200 ns ;
3 A side-effect of the process model: processes execute sequentially 33 wait ;
but the time steps should be regarded as arbitrarily small. 34 end p r o c e s s p h y s i c s ;

Page -11-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

35 5.3 Fixed-Point Math


36 t r i g g e r : muon_decay_trigger p o r t map (
37 c l k=>c l k , s=>pmt , t r i g=>d a q _ t r i g ) ;
38 end B e h a v i o r a l ;
There may arise the need to perform mathematical opera-
tions on real physical quantities in firmware. The DE0 Nano
board, for example, contains an accelerometer which reads
out 10-bit signed numbers with a range of ±2g. The map-
And the trigger code ping from digital count value, A to real acceleration value, a
is ( )
1 library ieee ; A
2 use i e e e . std_logic_1164 . a l l ; a= g (4)
3
256
4 use i e e e . numeric_std . a l l ;
5 This is known as fixed point representation of reals. How can
6 e n t i t y muon_decay_trigger i s you use this acceleration measurement to compute derived
7 port (
8 clk : in std_logic ;
physical quantities such as the velocity and the position?
9 s : i n s t d _ l o g i c _ v e c t o r (2 downto 0 ) ; First, let’s consider velocity. I suppose that you know how
10 t r i g : out s t d _ l o g i c ) ; to do this in theory:
11 end muon_decay_trigger ;
12
v = v0 + a∆t (5)
13 a r c h i t e c t u r e b e h a v i o r a l o f muon_decay_trigger i s
14
15 type mu_state_t i s ( The accelerometer reads a value every 0.02 s: how can we
16 i d l e , wait500 , wait15k , calculate the velocity change? This is tantamount to asking
17 triggered ); how to represent the ∆t quantity? We expect the range of
18 s i g n a l s t a t e : mu_state_t := i d l e ;
19 signal t , u : std_logic ;
possible ∆ts to be small, actually fixed at 0.02 s because the
20 FPGA should never skip a beat. So really there is only an
21 begin implict multiplication going on here; combining equations 4
22 t <= s ( 0 ) and s ( 1 ) and not s ( 2 ) ; and 5:
23 u <= s ( 1 ) or s ( 2 ) ;
24 t r i g <= ’ 1 ’ when s t a t e = t r i g g e r e d e l s e ’0 ’; v = v0 + (0.766 mm/s) · A (6)
25
26 s t a t e s : process ( clk )
Likewise to compute the position of the DE0 board,
27 v a r i a b l e count : i n t e g e r range 0 to 1499;
28 begin x = x0 + v∆t = x0 + (0.02 s) · v (7)
29 i f r i s i n g _ e d g e ( c l k ) then
30 case s t a t e i s again substituting the fixed interval, ∆t = 0.02 s.
31 when i d l e =>
32 i f t = ’ 1 ’ then The procedure for computing the realtime velocity and posi-
33 s t a t e <= wait500 ; tion of the DE0 is then the following:
34 count := 4 9 ;
35 end i f ; • Initialize the position and velocity to zero;
36 when wait500 =>
37 i f count /= 0 then • Readout the acceleration, A;
38 count := count − 1 ;
39 else • Update the velocity: vn ← vn−1 + A;
40 s t a t e <= wait15k ;
41 count := 1499; • Update the position: xn ← xn−1 + vn−1
42 end i f ;
In VHDL, this looks like the following. Assuming the fol-
43 when wait15k =>
44 i f u = ’ 1 ’ then lowing declarations in the declarative part of the architec-
45 s t a t e <= t r i g g e r e d ; ture,
46 e l s i f count /= 0 then
47 count := count − 1 ; s i g n a l ax : s t d _ l o g i c _ v e c t o r (9 downto 0 ) ;
48 else s i g n a l vx : s i g n e d (15 downto 0 ) ;
49 s t a t e <= i d l e ; s i g n a l x : s i g n e d (15 downto 0 ) ;
50 end i f ;
51 when t r i g g e r e d => The statements to update the position are:
52 s t a t e <= i d l e ;
53 end case ; update : p r o c e s s ( c l k )
54 end i f ; begin
55 end p r o c e s s s t a t e s ; i f r i s i n g _ e d g e ( c l k ) and accel_ok = ’ 1 ’ then
56 vx <= vx + s i g n e d ( ax ) ;
57 end b e h a v i o r a l ; x <= x + vx ;
end i f ;
end p r o c e s s update ;

Page -12-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

So far, it has not even been necessary to do any multiplica- which then repeats. Hardly a random sequence, but if you
tions! The units attached to the velocities and positions are make it long enough it looks random. In general it is possible
0.766 mm/s for velocity and 15.32 µm. To convert to more using an n bit register to produce an sequence of repetition
useful units, millimeters, it is necessary to divide by 65.274 length 2n − 1. Note that the sequence all zeros must be
(or, equivalently, multiply by 0.01532). This is pretty close excluded to prevent the sequence from getting stuck in that
to a power of two so you might consider your requirements state.
on accuracy: if the application can tolerate a 2% error, the
Getting the taps right is not trivial unless you are familiar
simplest approximation is to divide by 64, or equivalently,
with advanced algebra. Fortunately several magic taps have
shifting the bits to the right six steps:
been tabulated5 . Horowitz and Hill gives several suggestions
x_in_near_mm <= x (15 downto 6 ) ; for various LFSR lengths.
Producing random integers from the random bits is not dif-
If higher accuracy is needed, the least expensive method is to
ficult. Returning to the random bits above by taking every
use a rational approximation of the scaling factor where the
4th clock cycle (to avoid explicit bit correlations), a repeat-
denominator is a power of two, again we can profit from the
ing sequence of integers ranging from 1 to 15 can be pro-
ability to shift right instead of dividing4 . Luck is on our side:
duced:
0.01532 is very close to the rational number 251/16384 . We can
get an accuracy of %0.001 (way better than the acceleration 6, 13, 3, 2, 11, 14, 1, 9, 5, 15, 8, 12, 10, 7, 4, 6, ...
measurement, by the way, so be on guard to not overestimate Often, random numbers in the real interval (0, 1) are needed.
your accuracy!) by multiplying by 251 and then right shifting In the spirit of fixed-point numbers, discussed above, the ran-
14 bits. If we want to use the Cyclone IV’s 9×9 bit multiplier dom integer sequences can be interpreted as having implicit
hardware, the most efficient VHDL transformation is: scale factors. For example, the sequence above could be in-
tmp := t o _ s i g n e d (25 1 , 9) * x (15 downto 7 ) ; terpreted as representing the numbers
x_mm <= tmp(15 downto 7 ) ;
0.3750, 0.8125, 0.1875, 0.1250,
0.6875, 0.8750, 0.0625, 0.5625,
where tmp is an 18-bit signed variable defined to capture the
0.3125, 0.9375, 0.5000, 0.7500,
result of the 9 × 9 multiplication:
0.6250, 0.4375, 0.2500, 0.3750...
v a r i a b l e tmp : s i g n e d (17 downto 0 ) ;

Looking at the synthesis reports I see that the synthesizer 5.5 ROMs
has even gotten around using the multipliers! How? Multi-
plying x by 251 is equivalent to multiplying x by 256 (i.e. Read Only Memories are useful constructions to hold con-
left shifting by 8) and then subtracting x times 4 and finally stants and implement functions. Let’s start just by intro-
again subtracting x. Keep that trick in your pocket in case ducing the syntax for forcing VHDL to synthesize a ROM
you are using PLDs without hardware multipliers. using distributed storage elements (i.e. LEs). The ROM is
just an array of std_logic_vector types (array of bit arrays).
The VHDL syntax requires a 2-step definition; first, define
5.4 Pseudorandom Numbers the array element type, then define the array type and finally
declare a concrete constant object of this array type (lines
(see Horowitz and Hill section 9.33 pg 655) 12–14 in the listing below):
Apparently random sequences of bits can be generated using 1 library ieee ;
a FSM configuration known as the linear feedback shift reg- 2 use i e e e . std_logic_1164 . a l l ;
ister (LFSR). It is simply a shift register whose input bit is 3
4 e n t i t y romexa is
determined by taking XORs of various bit positions further 5 port (
into the register, these are often called taps. For example a 6 clk : in std_logic ;
4-bit LFSR could be constructed like this: 7 ce : in std_logic ;
8 data : out s t d _ l o g i c _ v e c t o r (7 downto 0 ) ) ;
9 end romexa ;
Q3 ← Q0 ⊕ Q1 (8)
10
11 a r c h i t e c t u r e b e h a v i o r a l o f romexa i s
This would then produce the bit sequence 12 s u b t y p e word_t i s s t d _ l o g i c _ v e c t o r (7 downto 0 ) ;
13 t y p e rom_t i s a r r a y (0 to 31) o f word_t ;
0110, 1011, 0101, 1010, 1101, 1110, 1111, 0111 14 c o n s t a n t mem : rom_t := (
0011, 0001, 1000, 0100, 0010, 1001, 1100, 0110
5 Of course, this is a security issue - don’t use these popular numbers
4 As a general rule, avoid expensive divisions whenever possible. for crypto applications othewise your ciphers will be easily cracked!

Page -13-
UW-Physics PHYS623 Introduction to Programmable Logic Devices

15 (”10000000”) , (”01000000”) , 34 begin


16 (”00100000”) , (”00010000”) , 35 f o r i i n 0 to 511 l o o p
17 (”00001000”) , (”00000100”) , 36 v := ( r e a l ( i )+0.5) / 5 1 2 . 0 ;
18 (”00000010”) , (”00000001”) , 37 r := s i n ( 2 . 0 *MATH_PI*v ) ;
19 (”00000010”) , (”00000100”) , 38 tmp( i ) := t o _ s i g n e d ( i n t e g e r ( r * 1 2 8 . 0 ) , 9 ) ;
20 (”00001000”) , (”00010000”) , 39 end l o o p ;
21 (”00100000”) , (”01000000”) , 40 r e t u r n tmp ;
22 (”00100000”) , (”00010000”) , 41 end i n i t _ s i n e r o m ;
23 (”00001000”) , (”00000100”) , 42
24 (”00000010”) , (”00000100”) , 43 signal sine : mem_t := i n i t _ s i n e r o m ;
25 (”00001000”) , (”00010000”) , 44 signal ln : mem_t := i n i t _ l o g r o m ;
26 (”00100000”) , (”00010000”) , 45 s i g n a l x , y , z : word_t ;
27 (”00000100”) , (”00001000”) , 46 b e g i n
28 (”00010000”) , (”00011000”) , 47 x <= l n ( t o _ i n t e g e r ( u n s i g n e d ( u ) ) ) ;
29 (”00100100”) , (”01000010”) , 48 y <= s i n e ( t o _ i n t e g e r ( u n s i g n e d ( v ) ) ) ;
30 (”10000001”) , ( ” 0 0 0 0 0 0 0 0 ” ) ) ; 49 z <= s i n e ( ( t o _ i n t e g e r ( u n s i g n e d ( v ))+128) mod 5 1 2 ) ;
31 b e g i n 50 n1 <= s t d _ l o g i c _ v e c t o r ( x* z ) ;
32 process ( clk ) 51 n2 <= s t d _ l o g i c _ v e c t o r ( x*y ) ;
33 v a r i a b l e addr : i n t e g e r range 0 to 31 := 0 ; 52 end a r c h i t e c t u r e rom ;
34 begin
35 i f r i s i n g _ e d g e ( c l k ) and ce = ’ 1 ’ then
36 data <= mem( addr ) ;
37 addr := ( addr + 1) mod 3 2 ;
38 end i f ;
39 end p r o c e s s ;
40
41 end b e h a v i o r a l ;

ROMs can be filled with more complicated patterns. An


example of this is used in the gaussian entity of the LED Snow
project. The method is to define a VHDL function which
generates (at compile time, so you can use real variables)
the ROM contents programmatically.
1 library ieee ;
2 use i e e e . std_logic_1164 . a l l ;
3 use i e e e . numeric_std . a l l ;
4 use i e e e . math_real . a l l ;
5
6 entity gaussian i s
7 port (
8 u, v : i n s t d _ l o g i c _ v e c t o r (8 downto 0 ) ;
9 n1 , n2 : out s t d _ l o g i c _ v e c t o r (17 downto 0)
10 );
11 end e n t i t y g a u s s i a n ;
12
13 a r c h i t e c t u r e rom o f g a u s s i a n i s
14 subt ype word_t i s s i g n e d (8 downto 0 ) ;
15 t y p e mem_t i s a r r a y (0 to 511) o f word_t ;
16
17 f u n c t i o n i n i t _ l o g r o m r e t u r n mem_t i s
18 variable r , u : real ;
19 v a r i a b l e tmp : mem_t := ( o t h e r s =>
20 ( o t h e r s => ’ 0 ’ ) ) ;
21 begin
22 f o r i i n 0 to 511 l o o p
23 u := ( r e a l ( i )+0.5) / 5 1 2 . 0 ;
24 r := s q r t ( −2.0* l o g ( u ) ) ;
25 tmp( i ) := t o _ s i g n e d ( i n t e g e r ( r * 6 4 . 0 ) , 9 ) ;
26 end l o o p ;
27 r e t u r n tmp ;
28 end i n i t _ l o g r o m ;
29
30 f u n c t i o n i n i t _ s i n e r o m r e t u r n mem_t i s
31 variable r , v : real ;
32 v a r i a b l e tmp : mem_t := ( o t h e r s =>
33 ( o t h e r s => ’ 0 ’ ) ) ;

Page -14-

You might also like