TRIBHUVAN UNIVERSITY
INSTITUTE OF ENGINEERING
PULCHOWK CAMPUS
PULCHOWK
A Report
On
Final Year Project
FPGA BASED SIGNAL GENERATOR
(EG777EX)
Submitted to:
Department of Electronics and
Computer Engineering
Pulchowk Campus
IOE
Submitted by:
Dipen Manandhar (061/BEX/419)
Jayesh Giri (061/BEX/422)
March 2009
TRIBHUVAN UNIVERSITY INSTITUTE OF ENGINEERING PULCHOWK CAMPUS PULCHOWK
A Report
On
Final Year Project
FPGA BASED SIGNAL GENERATOR
(EG777EX)
Submitted to:
Department of Electronics and
Computer Engineering
Pulchowk Campus
IOE
Submitted by:
Dipen Manandhar (061/BEX/419)
Jayesh Giri (061/BEX/422)
Project work submitted to the department in the partial fulfilment of the requirement
for the Bachelor of Engineering
March 2009
TRIBHUVAN UNIVERSITY INSTITUTE OF ENGINEERING PULCHOWK CAMPUS PULCHOWK
A Report
On
Final Year Project
FPGA BASED SIGNAL GENERATOR
(EG777EX)
Submitted to: Department of Electronics and
Computer Engineering
Pulchowk Campus
IOE
Submitted by:
Dipen Manandhar (061/BEX/419)
Jayesh Giri (061/BEX/422)
March 2009
ACKNOWLEDGEMENT
We are very grateful to all the people who supported us and rendered help from their side
in putting our theoretical knowledge into practice and help bringing out the performance close to
what we are capable of.
Firstly, our sincere gratitude goes to Prof Shashidhar Ram Joshi, Head of the Department for
making us available the required platform and resources and encouraging us to prepare for this
project. We are thankful to our project co-ordinator Asst. Prof. Dr Surendra Shrestha who
provided us the necessary information and equipments that proved extremely useful in our
project execution. We owe sincere obligations to our project supervisors Asst. Prof Jitendra
Kumar Manandhar and Mr Pradhumna Lal Shrestha for the encouragement and support they
provided us throughout the period of our project We had their guidance, support and skills at our
disposal that really proved worthwhile in our work , without which our project would not have
been completed.
Lastly, our thanks to Department of Electronics and Computer engineering as well as all the
friends and well wishers who offered their valuable suggestions during our project and guided us
through the cumbersome tasks that help put our project into shape after preparing the outline for
this project. We would also like to appreciate the help and cooperation provided by our campus
administration and hope that this passes on to the future batches of IOE.
Dipen Manandhar (061bex 419)
Jayesh Giri(061bex 422)
i
ABSTRACT
Signals of basic types such as square, ramp and sinusoidal are a basic necessity in any electronics
lab. We being integrally related to this field have undertaken the task of providing these signals
in an FPGA device. The equipments thus necessary for signal generation in our project consists
of an FPGA board and a DAC for converting the processed digital signal into analog form. The
digital circuitry required to make up a signal generator is programmed via VHDL(very high
speed integrated circuit hardware description language) and divided into modules. The different
modules that are programmed are those that will generate sine, triangular and rectangular waves.
We have used a varying square wave generating module that can generate clock pulses up to 200
MHz. However this clock is too much for the DAC that is present in our board which can
support a maximum of up to 50 MHz. Therefore we have divided this generated clock frequency
by certain factor to make it adequate for our DAC to function. The undivided clock frequency is
displayed in the LCD screen provided on board.
The DAC present in the Spartan 3E FPGA board required a parallel in serial out shift register
which converts a12 bit unsigned digital value into a 32 bit value with the required channel
identification code and command bits for the DAC which we have implemented as a separate
module inside the FPGA board. This shift register also generates handshake signals for
communicating with the SPI module inside the DAC.
As per the basic requirements of a conventional signal generator we should be able to
change the frequency, amplitude and offset values of the generated signal. The change in
frequency is achieved by supplying a clock that is varying in frequency. This varying clock
frequency providing module is accurate up to 200 MHz as already stated. The DC offsetting of
the generated signal is provided by a summing amplifier with two inputs. One of the inputs
would be varying DC to provide the required offsetting and the other input would be the
generated signal from the FPGA which has a certain DC offset. Finally the offset compensated
signal is amplified. For amplification purpose we have used an instrumentation amplifier with
varying gain. The gain is adjusted by a varying resistance within this instrumentation amplifier.
ii
List of Abbreviations
S.N. ABBREVIATION FULL-FORM
1 FPGA Field Programmable gate array
2 VHDL Very high speed integrated circuit hardware description
language
3 SPI Serial peripheral interface
4 LCD Liquid Crystal Display
5 VGA Video Graphics Adapter
6 CPLD Complex programmable logic devices
7 SMA Sub Miniature
8 DCM Digital Clock Manager
9 DDS Direct digital synthesis
10 ASIC Application Specific Integrated Circuit
11 CLB Configurable Logic Blocks
12 DAC Digital To Analog Converter
13 FSM Finite State Machine
14 RTL Register transfer Logic
15 HDL Hardware Description Language
16 LUT Look up tables
17 MAC Media access control
18 EEPROM Electrically Erasable Programmable ROM
19 USB Universal Serial Bus
20 DIP Dual inline package
21 SMT Surface Mount Technology
22 MOSI Master Output Slave Input
23 MISO Master Input Slave Output
iii
List of Figures
Fig No. Figure Page No
2.1 Sine wave with DC component 3
2.2 Square wave with DC component half its peak amplitude 4
2.3 Triangular wave with DC component 4
2.4 Ramp (sawtooth) wave with DC component 5
2.5 Flow process for implementing design in FPGA 8
2.6 Summary of VHDL design flow 9
3.1 Spartan- 3E starter board 11
3.2 DAC output locations in the Spartan 3E FPGA board 13
3.3 Digital to analog connection schematics 14
3.4 SPI communication timing diagrams 16
3.5 32 bit format for SPI buffer in LTC 2624 DAC 17
3.6 Op-amp instrumentation amplifier 19
3.7 Summing amplifier 20
3.8 The 8 bit picoblaze microcontroller and its internal block diagram 21
4.1 Overall hierarchical diagram with implementation constraints 22
4.2 Overall system block diagram 28
4.3 State wise representation of the sine wave generating module 29
4.4 State Representation of Triangular wave Generation Process 30
5.1 Sine wave output 33
5.2 Ramp wave output 33
5.3 Triangular wave output 34
5.4 Square wave output 34
5.5 Outputs at varying amplitude and frequency 35
iv
TABLE OF CONTENTS
Title Page No.
ACKNOWLEDGEMENT i
ABSTRACT ii
List of Abbreviations iii
List of Figures iv
1. Introduction 1
1.1 Objectives 1
2. Literature review 2
2.1 Basic types of wave and their properties 3
2.1.1 Sine, Triangular and Ramp waves 3
2.2 VHDL 5
2.2.1 History of VHDL 5
2.2.2 Benefits of using VHDL 6
2.3 Implementing Design in FPGA Board 8
3. Hardware Assessment 11
3.1 Spartan-3E FPGA board 11
3.1.1 Key components and features 12
3.2 Digital to Analog Converter (DAC)(LTC2624) 13
3.2.1 Interface signals 14
3.2.2 SPI communication 15
3.2.3 Communication Protocol 16
3.2.4 Specifying the ouput voltage for DAC 17
3.2.5 Application of LTC 2624 DAC 18
3.3 Three OP-Amp Instrumentation Amplifier 19
3.4 Summing Amplifier 20
3.5 The Picoblaze 8-bit Embedded Controller 21
4. Software approach 22
4.1 Software and Package Hierarchy 22
4.2 Entities used 23
4.3 Brief description of the wave generated modules 29
4.3.1 Sine wave generating module 29
4.3.2 Triangular wave generating module 30
4.3.3 Ramp wave generating module 31
4.3.4 The special spicom and spicom1 module 31
4.4 Frequency Variation 31
5. Results 32
5.1 Generated output wave 32
5.2 Signal generation range 32
5.3 Sample output 32
5.3.1 Sine wave 33
5.3.2 Ramp wave 33
5.3.3 Triangular wave 34
5.3.4 Square wave 34
5.4 Sample outputs at varying amplitude and frequency 35
6. Epilogue 36
6.1 Cost Analysis 36
6.2 Problems Faced and their solution 36
6.3 Application 37
6.4 Limitation 37
6.5 Recommendation and Conclusion 37
REFERENCES 39
APPENDIX 40
A.1 ADDENDUMS 41
1. Documents 41
Square wave generating module 41
Push button switches and Rotary encoders 44
LCD display 47
Clock sources 49
Slide switches 50
Picoblaze 51
2. Datasheets 52
Datasheet of LTC 2624 52
Datasheet of LM324 65
A.2 SOURCE CODES 67
1
CHAPTER 1
INTRODUCTION
Signals may be regarded as one of the important attributes of analysing and
experimentation in an electronic laboratory. Varying types of signals are generated by a
conventional signal generator. The basic types of waves generated by a signal generator are
used in different applications that include the fields of communication, biomedical
instrumentation as well as education and research. In communication signals can be
modulating ones or modulated ones, which thus packs a need for an oscillator which can
generate basic signals that can modulate baseband signals. The signals are equally important
in anatomical and biomedical research where certain sets of inputs are required for test and
diagnosis. Even in the area of academic research and analysis, a signal generator is a must
and a sophisticated one as present in our lab may cost thousands of rupees and easily exceed
the cost of the components used in our project.
The signal implemented in FPGA generate signals up to 200 MHz with accurate
precision. The control of frequency of this square wave is achieved by taking the inputs from
the user via input equipments placed inside the FPGA board. This clock frequency itself acts
a square wave to be produced by the generator. The generated clock frequency thus
comfortably exceeds the frequency of square wave generated by a conventional signal
generator. The sine wave, saw tooth wave and the ramp wave however require one complete
cycle of conversion of the digital values into analog one and thus have a much lower
frequency.
1.1 Objectives
The main objective of our project is to achieve some of the basic features of a conventional
signal generator using a single FPGA device . The generated signal would test the limits of
the FPGA board used. As far as possible we have used the components present within the
FPGA board used. It thus shows the application of one of the innovative advances in
embedded systems in something as fundamental as signal generation. The system also
provides an alternative to contemporary signal generator used in lab.
2
CHAPTER 2
LITERATURE REVIEW
A conventional signal generator used in the lab can synthesize frequencies only up to
1 MHz. Signals of values larger than this could have been synthesized, but this would be
beyond the scope of an archetypal electronics laboratory. The signals to be generated is
obviously the fundamental purpose behind the project. Up to now we had learnt to synthesize
signals using oscillators that used discrete components. The use of these discrete components
to synthesize signals add complexities to the process of signal generation. The control of the
characteristics of the signals adds further intricacies to an already complex system. The
signals generated may not be trustworthy and can be subjected to noise and distortion. FPGA
being a new technology, and the most advanced applications in embedded systems can
accurately generate controllable functions.
The signals to be synthesized are in fact nothing but digital values. These digital
values are a combination of binary digits that can suitably be converted to an analog value
using a digital to analog converter(DAC). The binary values are synthesized using modules
that are programmed inside the FPGA. Each module has a specific function that are designed
to perform a specific function. A variety of functionalities can be added by the combination
of these modules. For the purpose of signal generation separate modules are used to generate
sine, triangular and ramp functions. These modules send a range of data to the DAC for the
production of sine, triangular and ramp function. For the convenience of the user, data to be
input to the DAC is fed to a multiplexer with its selection lines to be controlled by the user.
Frequency control of the signals is provided by varying the clock signals going into the wave
generating modules. The synthesized data has a constant amplitude level, since the reference
voltage to the DAC cannot be changed. Therefore for the conditioning of the signal has to
be carried outside the FPGA using a suitable amplitude adjustment circuit. The most common
and appropriate amplifier that can be used is the 3- op amp instrumentation amplifier. The
output still contains a high frequency noise that may be removed using a suitable filter.
Minimizing the components to be used is one aspect while the control of the signal
generated is another aspect. To meet both of these requirements modules may be added that
also provide further sophistication to the signal generating system designed.
3
2.1 Basic types of waves and their properties
2.1.1 Sine, triangular and ramp waves
A sinusoidal wave is the most fundamental in electronics and communication realm. It is a
well known fact that each and every signal is composed of finite or infinite summations of
sine and cosine waves of constant or varying amplitudes. This fact can also be proved from
the fourier analysis of the signals.
Fig 2.1 sine wave with DC component
The mathematical decomposition of the composite signals into their individual
components can also be realised practically by filtering out only one of the component. A
sinusoidal wave can be represented by a generalised wave equation which is
f(t)=Asin(2πft+ϕ) where A represents the amplitude, f represents frequency and ϕ represents
the phase shift. Amplitude represents the strength of the signals frequency. The periodic
variation in timing is characterized by the frequency f. The generated sinusoidal wave may
contain DC component i.e. the signal is below or above the actual ground. There are various
techniques to remove this DC component which will be discussed later.
Square wave is characterized by instantaneous transitions from one DC value to the
another. The square wave is important in the sense that it provides clock pulses for the digital
circuits. Square waves are composed of higher frequency harmonics, which is in fact the
main cause for the digital circuits to be more noisier than analog circuits. It is one of the
valuable tools for analysing digital circuits. The DC levels in a simple clock pulse can be
4
suitably adjusted to generate the desired frequency square wave. It is also designated as
Rademacher function.
Vmax
0
Fig 2.2 Square wave with DC component half its peak amplitude
A triangular wave is a periodic wave characterized by linear rise and fall of the signals. The
signal rises linearly up to a certain point and then decreases linearly from the same point to a
fixed low value. The shape thus resembles two sides of a triangle hence appropriately
designated as triangular wave. The triangular wave is most commonly used in signalling
applications where testing of a circuitry is required as well as system response to such a
wave.
Vmax
Vmin
0
Fig 2.3 Triangular wave with DC component
A ramp wave is most commonly known as sawtooth wave since the wave shape resembles
the blades of a saw. This wave rises linearly upto a certain value and decreases from that
value instantaneously to a lower peak value. One complete cycle of the wave resembles two
sides of a right angled triangle. The ramp wave rises linearly up to some level. So in fact a
periodic linear response to a system can be evaluated using this kind of wave as input.
5
Vmax
Vmin
0
Fig 2.4 Ramp (sawtooth) wave with DC component
2.2 VHDL
VHDL is a hardware description language that describes the behavior of an electronic circuit
or system. The behavior determines physical circuit to be attained(implemented). The full
form is in fact VHSICHDL which means very high speed integrated circuit hardware
description language, an initiative funded by the United States Department of defense in the
1980s. VHDL is intended for circuit synthesis as well as circuit simulation. However though
VHDL is fully simulatable, not all constructs are synthesizable. A fundamental motivation to
use VHDL is that VHDL is a standard, technology/vendor independent language and is
therefore portable and reusable. Two main immediate applications of VHDL are field of
programmable logic devices(CPLDs) and FPGAs. Once written a VHDL code it can be
implemented in circuit in a programmable device or can be submitted to a foundary for the
fabrication of an ASIC chip.
2.2.1 History of VHDL
VHDL arose out of the United States government‟s Very High Speed Integrated Circuits
(VHSIC) program.In the course of this program, it became clear that there was a need for a
standard language for describing the structure and function of integrated circuits (ICs).Hence
,the VHSIC Hardware Description Language (VHDL) was developed .It was subsequently
developed further under the auspicious of the Institute of Electrical and Electronic Engineers
(IEEE) and adopted in the form of the IEEE Standard 1076,Standard VHDL language
6
Reference Manual ,in 1987.This first standard version of the language is often referred to as
VHDL-87.
Like all IEEE standards ,the VHDL standard is subject to review at least every five years.
Comments and suggestions from users of the 1987 standard were analysed by the IEEE
working group responsible for VHDL, and in 1992 a revised version of the standard was
proposed .This was eventually adopted in 1993,giving us VHDL-93.A further round of
revision of the standard was started in 1998.That process was completed in 2001.In 2002,the
current VHDL standard(IEEE-1076-2002) was adopted.
2.2.2 Benefits of using VHDL
i) Executable Specification
It is often reported that a large number of FPGA designs meet their specifications first time
,but fail to work when plugged into a system. VHDL allows this issue to be addressed in two
ways: A VHDL specification can be executed in order to achieve a high level of confidence
in its correctness before commencing design and may simulate one to two orders of
magnitude faster than a gate level description .A VHDL specification for a part can form the
basis for a simulation model to verify the operation of the part in the wider system context
(e.g. printed circuit board simulation).This depends on how accurately the specification
handles aspects such as timing and initialization.
Behavioral simulation can reduce design time by allowing design problems to be detected
early on, avoiding the need to rework designs at gate level Behavioral
Simulation also permits design optimization by exploring alternative architectures, resulting
in better designs.
ii)Tools
VHDL descriptions of hardware design and test benches are portable between design tools,
and portable between designs centers and project partners. We can safely invest in VHDL
modeling effort and training ,knowing that will not be tied into a single tool vendor ,but will
be free to preserve our investment across tools and platforms. Also, the design automation
tool vendors are themselves making a large investment in VHDL, ensuring a continuing
supply of state-of-the-art VHDL tools.
7
iii)Technology
VHDL permits technology independent through support for top down design and logic
synthesis. To move a design to new technology you need not start from scratch or reverse
engineer a specification instead you go back up the design tree to a behavioral VHDL
description, then implement that in the new technology knowing that the correct functionality
will be preserved.
Benefits in brief
Executable specification
Validate spec in system context(Subcontract)
Functionality separated from implementation
Simulate early and fast(Manage complexity )
Explore design alternatives
Get feedback (Produce better designs)
Automatic synthesis and test generation (ATPG for ASICs)
Increase productivity (Short time-to-market)
Technology and tool independence (though FPGA features may be unexploited)
Portable design data(Protect investment)
8
2.3 Implementing Design in the FPGA Board
Fig 2.5 Flow process for implementing design in FPGA
The first step towards implementing a design is the entry of designed module in HDL. The
VHDL and verilog design entry tools are built in to the ISE 10.1 software that we use.
Language templates of most commonly used logical designs are present and can be readily
used as per the requirements. Besides there are ready to use IP cores and tools such as
chipscope pro core inserter tools that can add cores(ready to use modules) to an existing
FPGA design. These cores can also be inserted in the post synthesis netlist without
disturbing HDL source code. The design constraints that include timing constraints as well as
supported architectures and applicable elements can also be added in the entry phase. During
design synthesis phase the entered HDL schematic is transformed into a netlist at gate level,
which shows how the logical designed specified by HDL are interconnected. This netlist can
be viewed using RTL schematic viewing tool present in the ISE. Both the design entry and
9
design synthesis are subjected to behavioral simulation where we verify if our design is
working properly or not and the if the HDL source code is free from bugs.
Fig 2.6 Summary of VHDL design flow.
The behavioral simulation tools include testbenches, waveforms and timing diagrams.
During implementation of a design, the synthesized netlist is mapped into an FPGA device.
The configurable logic blocks(CLBs) inside FPGA device can be further decomposed into
look up tables and interwoven using various routing sources. The netlist gates are collected
by mapping tools into groups that fit into LUTs and place and route tools assigns the group to
specific CLBs while opening and closing switches to connect them together. The design
implementation phase is itself subjected to functional and timing simulations. After the
implementation the program extracts the state of switches in the routing matrices where the
opened and closed switches are detected and a bitstream is generated. The bitstream is finally
downloaded into an FPGA device. The download tools include on board USB-based JTAG
programming interface. There are also three different configuration memory sources that all
need to function together. The variety of configuration options include
10
Downloading FPGA designs directly to the Spartan-3E FPGA via JTAG, using the onboard
USB interface. The on-board USB-JTAG logic also provides in-system
programming for the on-board Platform Flash PROM and the Xilinx XC2C64A CPLD.
SPI serial Flash and StrataFlash programming are performed separately.
Programming the on-board 4 Mbit Xilinx XCF04S serial Platform Flash PROM, then
configuring the FPGA from the image stored in the Platform Flash PROM using Master
Serial mode.
Programming the on-board 16 Mbit ST Microelectronics SPI serial Flash PROM, then
configuring the FPGA from the image stored in the SPI serial Flash PROM using SPI
mode.
Programming the on-board 128 Mbit Intel StrataFlash parallel NOR Flash PROM, then
configuring the FPGA from the image stored in the Flash PROM using BPI Up or BPI
Down configuration modes. Further, an FPGA application can dynamically load two
different FPGA configurations using the Spartan-3E FPGA‟s MultiBoot mode.
The Xilinx Webpack(10.1) provides all the necessary HDL text editors, logic
synthesizers, implementation tools(translate, map and place and route) utilities for
downloading a design into the FPGA chip on board.
11
CHAPTER 3
HARDWARE ASSESSMENT
3.1 Spartan -3E FPGA board
The Spartan-3E starter kid highlights the unique features of Spartan-3E FPGA family and
provides a convenient development board for embedded processing applications.
Fig. 3.1 Spartan- 3E starter board
The board highlights these features:
Spartan-3E specific features
Parallel NOR Flash configuration
Multiboot FPGA configuration from Parallel NOR Flash PR
SPI serial Flash configuration
Embedded Development
MicroBlaze 32-bit Embedded RISC processor
PicoBlaze 8-bit embedded controller
DDR memory interfaces
12
3.1.1 Key components and Features
The key features of the Spartan-3E Starter Kit board are:
•Xilinx XC3S500E Spartan-3E FPGA
♦Up to 232 user-I/O pins
♦320-pin FBGA package
♦Over 10,000 logic cells
•Xilinx 4Mbit Platform Flash configuration PROM
•Xilinx 64-macrocell XC2C64A CoolRunner CPLD
•64 MByte (512Mbit) of DDR SDRAM, x16 data interface, 100+MHz
•16 MByte (128Mbit) of parallel NOR Flash (Intel StrataFlash)
♦FPGA configuration storage
♦MicroBlaze code storage/shadowing
•16 Mbits of SPI serial Flash (STMicro)
♦FPGA configuration storage
♦MicroBlaze code shadowing
•2-line, 16-character LCD screen
•PS/2 mouse or keyboard port
•VGA display port
•10/100 Ethernet PHY (requires Ethernet MAC in FPGA)
•Two 9-pin RS-232 ports (DTE- and DCE-style)
•On-board USB-based FPGA/CPLD download/debug interface
•50MHz clock oscillator
•SHA-1 1-wire serial EEPROM for bitstream copy protection
13
•Hirose FX2 expansion connector
•Three Digilent 6-pin expansion connectors
•Four-output, SPI-based Digital-to-Analog Converter (DAC)
•Two-input, SPI-based Analog-to-Digital Converter (ADC) with
programmable-gain pre-amplifier
•ChipScope™ SoftTouch debugging port
•Rotary-encoder with push-button shaft
•Eight discrete LEDs
•Four slide switches
•Four push-button switches
•SMA clock input
•8-pin DIP socket for auxiliary clock oscillator
3.2 Digital to analog converter (DAC) (LTC 2624)
The Spartan-3E Starter Kit board includes an SPI-compatible, four-channel, serial Digital-to-
Analog Converter (DAC). The DAC device is a Linear Technology LTC2624 quad DAC
with 12-bit unsigned resolution. The four outputs from the DAC appear on the J5 header,
which uses the Digilent 6-pin Peripheral Module format. The DAC and the header are located
immediately above the Ethernet RJ-45 connector, as shown in Figure:
Fig 3.2 DAC output locations in the Spartan 3E FPGA board.
14
FPGA uses a Serial Peripheral Interface (SPI) to communicate digital values to each of
the four DAC channels. The SPI bus is a full-duplex, synchronous, character-oriented
channel employing a simple four-wire interface. A bus master—the FPGA in this example—
drives the bus clock signal (SPI_SCK) and transmits serial data (SPI_MOSI) to the selected
bus slave—the DAC in this example. At the same time, the bus slave provides serial data
(SPI_MISO) back to the bus master. As shown below in figure:
Fig. 3.3 Digital to analog connection schematics
3.2.1 Interface signals
Table 3.1 lists the interface signals between the FPGA and the DAC. The SPI_MOSI,
SPI_MISO, and SPI_SCK signals are shared with other devices on the SPI bus. The
DAC_CS signal is the active-Low slave select input to the DAC. The DAC_CLR signal is the
active-Low, asynchronous reset input to the DAC.
15
Table 3.1: DAC interface signals
The serial data output from the DAC is primarily used to cascade multiple DACs. This
signal can be ignored in most applications although it does demonstrate full-duplex
communication over the SPI bus.
The SPI bus signals are shared by other devices on the board. It is vital
that other devices are disabled when the FPGA communicates with the DAC to avoid bus
contention. Table: provides the signals and logic values required to disable the other devices.
Although the StrataFlash PROM is a parallel device, its least-significant data bit is shared
with the SPI_MISO signal.
Table 3.2 : Disabled devices on the SPI bus
3.2.2 SPI Communication Details
Figure: 3.4 shows a detailed example of the SPI bus timing. Each bit is transmitted or
received relative to the SPI_SCK clock signal. The bus is fully static and supports clocks rate
up to the maximum of 50MHz. However, it is important to check timing parameters using the
LTC2624 data sheet if operating at or close to the maximum speed.
16
Figure 3.4: SPI communication timing diagrams
After driving the DAC_CS slave select signal Low, the FPGA transmits data on the
SPI_MOSI signal, MSB first. The LTC2624 captures input data (SPI_MOSI) on the rising
edge of SPI_SCK; the data must be valid for at least 4ns relative to the rising clock edge.The
LTC2624 DAC transmits its data on the SPI_MISO signal on the falling edge of SPI_SCK.
The FPGA captures this data on the next rising SPI_SCK edge. The FPGA must read the first
SPI_MISO value on the first rising SPI_SCK edge after DAC_CS goes Low. Otherwise, bit
31 is missed. After transmitting all 32 data bits, the FPGA completes the SPI bus transaction
by returning the DAC_CS slave select signal High. The High-going edge starts the actual
digital-to-analog conversion process within the DAC.
3.2.3 Communication protocol
Figure: shows the communications protocol required to interface with the LTC2624 DAC.
The DAC supports both a 24-bit and 32-bit protocol. The 32-bit protocol is shown. Inside the
D/A converter, the SPI interface is formed by a 32-bit shift register. Each 32-bit command
word consists of a command, an address, followed by data value. As a new command enters
the DAC, the previous 32-bit command word is echoed back to the master. The response
from the DAC can be ignored although it is a useful to confirm correct communication.
17
Figure 3.5: 32 bit format for SPI buffer in LTC 2624 DAC
The FPGA first sends eight dummy or “don‟t care” bits, followed by a 4-bit command.
The most commonly used command with the board is COMMAND[3:0] = “0011”, which
immediately updates the selected DAC output with the specified data value. Following the
command, the FPGA selects one or all the DAC output channels via a 4-bit address field.
Following the address field, the FPGA sends a 12-bit unsigned data value that the DAC
converts to an analog value on the selected output(s). Finally, four additional dummy or don‟t
care bits pad the 32-bit command word.
3.2.4 Specifying the output voltage for DAC
Each DAC output level is the analog equivalent of a 12-bit unsigned digital value,
D[11:0], written by the FPGA to the DAC via the SPI interface. The voltage on a specific
output is generally described in Equation:. The reference voltage, VREFERENCE, is different
between the four DAC outputs. Channels A and B use a 3.3V reference voltage and Channels
C and D use a 2.5V reference. The reference voltages themselves have a ±5% tolerance, so
there will be slight corresponding variances in the output voltage.
18
DAC outputs A and B
Equation below provides the output voltage equation for DAC outputs A and B. The
reference voltage associated with DAC outputs A and B is 3.3V±5%.
%)
DAC outputs C and D
Equation below provides the output voltage equation for DAC outputs A and B. The
reference voltage associated with DAC outputs A and B is 2.5V±5%.
3.2.5 Applications of LTC2624 DAC
Mobile Communication
Process Control and Industrial Automation
Instrumentation
Automatic Test Equipment
19
3.3 Three Op-Amp Instrumentation Amplifier
Instrumentation amplifier is a differential amplifier with extremely high input
impedance(avoids loading to transducers),high common mode rejection ratio(which makes it
very useful in recovering small signals buried in large common mode offsets and noise)and
precise gain setting control by using resistors. It is required in any measurement system to
enhance the signal level(millivolt range) for the further processing.
For our project, since the output voltage from the digital signal generator varies only
from 0V to 3.3V,we have used the 3 op-amp instrumentation amplifier for the further
amplification of the amplitude of the voltage. The below given circuit diagram depicts the 3
op-amp instrumentation amplifier, we have used for our project.
Fig 3.6: op-amp instrumentation amplifier
From the figure we have,
When ,R1=R3 ,R7=R5 and R4=R6
VO=(R5/R3)(VO2-VO1)
20
=(R5/R3)(V2-V1)(1+2R4/RV1)
For our project ,we have assigned R5=R3=R4=10kΩ and also R1=10kΩ=R7
VO=(1+(2*10000)/RV1) (V2-V1)
VO/(V2-V1)= 1+(2*10000)/RV1
Hence,
Gain=1+(2*10000)/RV1
So ,with varying the value of RV1 we can change or vary the gain of our amplifier.
Also, we have fed the ground as an input to V2.To V1,the output from the dc offsetting circuit
is fed to amplify the amplitude.
For the 3 op-amp instrumentation amplifier, we have used the integrated circuit LM324 to
which we have supplied two voltage level as ±15V.
3.4 Summing amplifier
To reduce the DC levels of the signals output from the DAC we need a summing amplifier.
V1
Vo
V2
Fig3.7: Summing amplifier
R R
R
21
The output voltage from the op amp depicted in the figure above is given by the equation
Vo= -(V1+V2)
The DAC inside an FPGA performs digital to analog conversion of only unsigned digital
values. The output of the DAC is thus never below zero. Therefore the signal generated in
analog form inherently possesses a DC component. The DC component presents a certain DC
offset value, that needs to be removed. One way of doing this is by passing it through a
suitable high pass filter. But designing a filter to remove just a DC offset value from the input
signal does not justify the purpose of filter design. Therefore passing the signal through the
V1 input of the summer, and adjusting a suitable DC voltage at V2 effectively removes the DC
component present in the signal. This signal can now be passed to an amplifier for signal
conditioning.
3.5 The picoblaze 8 bit embedded controller
We could have put this under software heading, but since it exhibits properties similar to that
of a conventional 8 bit microcontroller in hardware , it is more appropriate to deal with it in
hardware section. It is a single microcontroller module inside FPGA most commonly known
as KCPSM3 which is in fact a very simple a very simple 8 bit microcontroller primarily for
Spartan 3 devices. Although it could be used for processing data it is most likely to be
employed in applications requiring a complex but non-time critical state machine
Fig 3.8: The 8 bit picoblaze microcontroller and its internal block diagram.
We have used an existing picoblaze design for generating varying clock pulses up to 200
MHz which can also be used as a square wave. More about picoblaze and its resources in the
appendix section.
22
CHAPTER 4
SOFTWARE APPROACH
4.1 Software and package hierarchy
The software that we have formulated is designed to generate triangular, ramp and
sinusoidal waves at a fixed frequency. We have used separate modules to generate these
waves. Again it needs to be stressed out that the data that is generated is digital in nature and
is a combination of binary bits. The clock frequency that is generated by the square wave
generating module has a maximum value of 200 MHz. This frequency may have been used
directly as clock source but the DAC that is present inside the board(LTC2624) does not
support frequency as high as this. The DAC as we have shown above works at frequencies up
to a max of 50 MHz. Therefore this frequency is divided 8 times before feeding it to the
signal generating modules. A separate clock dividing module thus has been implemented in
our design.
The design as implemented in our project include interconnection of modules that are
defined by a hierarchy of designs. The hierarchical model can appropriately be shown by the
following tree diagram
Fig4.1: Overall hierarchical diagram with implementation constraints
23
4.2 Entities used
i) frequency_generator
This entity is the highest in the hierarchical list. The main function of this module is
to interconnect all the modules that are present immediately below it in the hierarchy as well
as provide number of preset values to the signals defined within the modules.
Ports within frequency generator
sma_out: Divided square wave output
simple: Signal output to J4 header
led: Output signals to the led
strataflash_oe, strataflash_ce, strataflash_we: Signals to disable strata flash memory
prevent interference with LCD
display
lcd_d: Bidirectional lcd data
buton1,buton2,buton3: Selection signals for triangular, ramp
and sine waves.
rst: Reset signal
spi_sck, dac_clr, dac_cs, sdi: Signals to be input into the DAC
sineot: 12 bit digital value for testing purpose
lcd_rs, lcd_rw, lcd_e: Handshake signals to the lcd
rotary_a, rotary_b, rotary_press: Input from the rotary encoder
ii) kcpsm3
It is in fact an 8 bit embedded microcontroller or most commonly known as the picoblaze.
The picoblaze has been implemented here in the varying clock generation process by
providing the values of the variables D and N through the inputs from the rotary encoder as
well as the display values for the lcd.
i/o ports for kcpsm3
24
address: 10 bit address of instruction present in the program ROM
instruction: 18 bit instruction
port_id: 8 bit address of the i/o port
write_strobe, read_strobe: Signals for writing to or reading from one of the 16 registers
present in the kcpsm3
out_port: One of the 256 output ports
interrupt: Interrupt signal to the kcpsm3 microcontroller
in_port: One of the 256 input ports
interrupt_ack: Interrupt acknowledge signal from the controller
reset: Reset signal that forces the processor into initial state
clk: Input clock signal for the processor
iii) fg_ctrl
Every microcontroller needs a program memory ROM. This program memory ROM is
here is represented by fg_ctrl. It simply has a 10 bit input ROM memory address and each
address can hold 18 bit instruction. An assembler generates VHDL template for the program
ROM with the assembly file input to it.
The i/o ports of this entity are
address: 10 bit instruction address
instruction: 18 bit instruction
proc_reset: reset pin for the program ROM
clk: clock signal to the ROM
iv) freqdiv
This entity/module simply inputs a clock signal, divides it by 8 and outputs it.
Therefore it has one input port clkin and one output port clkout.
25
v) freqdiv.ucf
An implementation constraint file that contains the pin configurations from the FPGA
device as well as timing constraints
vii) conn
This entity is simply the interconnection of the sine wave, triangular wave and ramp
wave modules along with the multiplexer and DAC interfacing module. The interconnection
is illustrated later along with the schematics. It has three selection lines „but1, but2 and but3‟
that serve as input for selecting sine, triangular and rampwave. It also outputs signals d_clr,
d_cs, sd and clkot for interfacing with the DAC.
viii) spicom
This module is used for communicating signals to the LTC2624 DAC. Since the DAC
takes data serially it is nothing but a parallel in serial out register. It takes in 12 bit unsigned
data, converts it into 32 bit data and then transmits it serially. The 32 bits within them also
contain the command words and channel address. It then indicates with an appropriate signals
after all the 32 bits are transmitted. Its i/o ports are
sin_ip: 12 bit parallel unsigned data
clk: input clock
load: indicating signal for loading the spicom with parallel
data
sdi: serial data input to the DAC
dac_cs: active low chip select signal for DAC
ack: acknowledgement signal after spicom has transmitted
all 32 bits of data
dac_clr: active low signal for resetting the DAC
26
clk1: output clock(bypassed) from the spicom
ix) spicom1
This module is similar to spicom with the exception that it does not bypass clock. It
interfaces only triangular wave to the DAC. All the i/o signals are similar as in spicom except
for the fact that clkot is not present.
x) sine_wave
This entity is used to generate digital values for sine wave. For the generation of sine wave
it uses s separate look up table. The look up table is stored in a separate package. The look up
table contains 16 different values within a range of 0 to 90 degrees and each in turn is
represented by a 4 bit value. The values are different for positive as well as for negative
cycle. The i/o ports in the module are as follows
clock: input clock to the sine wave generating module
reset: signal resetting the input and start from 0 degrees
enable: signal to stop/resume the generation of sine wave
wave_out: 12 bit unsigned digital value representing a sine wave value
xi) triwv
This entity is used to generate triangular wave output from the FPGA device. The
triangular wave as discussed earlier increments linearly from a minimum DC value and then
after reaching a maximum value again decrements to the same minimum value. The increase
and decrease of the signals is linear in nature.. Similar to sine wave generating module ,it has
the following i/o ports
clk: clock inout to the triangular wave generating module
enable: input to stop/ resume the generation of the triangular wave
reset: signal for resetting the wave generation process in the triangular wave
generating module
27
waveot: 12 bit unsigned value representing a triangular value
xii) rmpwv
This entity is used for generating a ramp wave. The ramp wave generated counts linearly
upto a maximum DC value from the minimum DC value. The output thus represents the
blades of a saw. This entity too has i/o ports similar to that of the triangular, sine and ramp
wave generating modules. The i/o ports of this module are
clk: input clock signal to the remp wave generating module
enable: pin to stop/resume the generation of the ramp wave.
reset: signal to reset the output wave from the initial(minimum) DC value
datout: output data(12 bit unsigned value) from the signal generator
xiii) spimulplx
This module is nothing but a simple multiplexer. It inputs three different groups of signals
for communicating with the DAC. These three sets of inputs arrive from sine, triangular and
ramp wave generating module that are used to communicate to the LTC2624 DAC. Only one
of the three signals are bypassed depending upon the signals present to the selection lines. For
the ease of selection there are three select lines, that each correspond to sine, triangular and
ramp wave generation. The i/o ports used here include
clock: input clock signal to the multiplexer
d_cs_tri, sd_tri, d_clr_tri: signals from the triangular wave generating module
to the DAC
d_cs_rmp, sd_rmp, d_clr_rmp: signals from the ramp wave generating module to the
DAC
d_cs_sin, sd_sin, d_clr_sin: signals from the sin wave generating module to the DAC
28
Fig 4.2: overall system block diagram
The system block diagram depicts the interconnection of the components inside the
FPGA device. Each module performs specified functions . The square wave generating
module synthesizes frequencies accurately up to 200 MHz, that can be taken out straight
away. Not only does the module square wave generate but this generated square wave also
functions as a clock frequency to the sine, triangular and ramp wave generating modules. The
spicom or the modules required to communicate the output signals to the DAC also require
clock signals. These clock signals are the same ones that are synthesized from the square
wave generating module.
All the modules are embedded within the FPGA chip which can support very high
clock frequencies. The DAC however is a separate chip outside the FPGA and therefore does
29
not support this high frequency. The maximum frequency that it can support is 50 MHz clock
which is provided in the spi_sck pin present at the input of the DAC. Frequency any higher
than this and we risk impairing the normal operation of the DAC. Therefore to overcome this
problem we have implemented a clock dividing module that divides the input clock
frequency eight times. So the maximum frequency that it can output now becomes
200/8=12.5 MHz. This frequency division ensures the normal operation the DAC preset in
the FPGA board. The spicom modules are used to input parallel data from the wave
generating modules, add necessary command information and then output it serially to the
DAC. The role of the multiplexer is simply to transfer one of the three inputs provided to it to
the output depending upon the selection lines. The input from the rotary encoders help
change the synthesized square wave frequency and thus used to vary the clock pulses from
the encoders. The slide switches are directly connected to the selection lines of the
multiplexer and hence offer the choice of selecting either the sine, triangular or the ramp
wave. The rotary encoders together with the slide switches and the lcd provide the human
interface required.
4.3 Brief description of the wave generating modules
4.3.1 Sine wave generating module
The sine wave generating module is designed to operate using FSM approach. The entire
module operates at four possible states as shown in the figure
Fig 4.3 state wise representation of the sine wave generating module
30
The state counting_up represents one fourth of the one complete cycle of the sine wave. It
represents 16 possible values in the interval of 0 to 90 degrees. Similarly the state
counting_down represents outputs another 16 values in the interval from 90 to 180 degrees.
For the negative cycle we have chosen another 16 values. The first 16 values for positive and
the negative cycle are only used and for the counting_down state we have used the same
values but in the decreasing order.
There are a maximum of 64 table values in one complete cycle of the sine wave. Each
value requires 32 clock cycles to load via shift register to the DAC buffer. Each shift from the
register requires at least one clock cycle. We have divided the clock from the square wave
generating module 8 times. This clock has a maximum value of 200 MHz. So we can expect
a maximum frequency of the sine wave to be 200/(64*32*8)=0.012 MHz or 12.2 Khz.
4.3.2 Triangular wave generating module
The triangular wave generating module also uses FSM approach. This module uses two
states count_up and count_down. In the count_up state the module counts from a minimum
dc value up to the maximum dc value. The minimum value is 200 and the maximum value is
3000 represented as 12 bit in unsigned format. The counting starts from 200 and increments
by 100 upto 3000 and then decreases by 100 until it again reaches to 200.So there are total of
28*2=56 values in one completed cycle of the triangular wave.32 clock cycles are required to
load single value to the DAC via shift register. So each shift similar to above requires at least
one clock cycle. Therefore we can expect maximum frequency of the triangular wave to be
200/(56*32*8)=0.0139MHz or 13.9Khz.
Fig 4.4 :State Representation of Triangular wave Generation Process
31
4.3.3 Ramp wave generating module
This module is implemented without the use of states. The 12-bit unsigned value simply is
incremented from a minimum of 200 upto 3000.The incrementing value in this case is only
10. So we have 280 unsigned 12-bit values representing one complete cycle of the ramp
wave. So with the maximum clock frequency of 200Mhz and 32 clock cycles to shift one
value into the DAC buffer and finally 8 divisions of the clock we can expect the maximum
frequency of200/(280*32*8)=0.0028MHz or 2.8KHz.
4.3.4 The special spicom and spicom1 modules
For the purpose of interfacing with the 32-bit register inside the DAC we have designed
a separate communicating module that we have named as spicom. The spicom differs from
spicom1 from the fact that it also bypasses clock. This spicom module is infact a special type
of parallel in serial out register. It takes 12-bit unsigned data parallely, adds necessary
informations to it to make 32-bit value and transmits it serially. Whenever the load input to it
becomes high the 12-bit unsigned value is instantly loaded into this PISO. After it has
transmitted all the 32-bits of data serially it asserts dac_cs signal high so that another 12-bit
value can again be loaded. This action also enables the wave generating module connected to
it so that the wave generation process can continue and the and next value can be output to
the spicom module. The detail of all the connection inside FPGA can be viewed in the RTL
schematic diagram in the next page.
4.4 Frequency Variation
Frequency as we know varies as the time required to complete one cycle increases. This
increment as well as decrement of the time required to complete one cycle of the wave is
what actually varies the frequencies of sine, triangular and ramp waves. Now as shown
above, the input clock frequency to the square, triangular and ramp modules is from the
square wave generating module itself. Hence variation in this clock frequency from the
square wave generating module also varies the frequency of the sine, triangular and ramp
wave generated. However with number of subdivisions to this clock before applying to the
modules and number of values required to complete one complete cycle of the wave, means
that the generated wave frequency is divided by a constant factor from the display of the
frequency of the square wave generated in the LCD screen.
32
CHAPTER 5
RESULTS
5.1 Generated output wave
The output wave was generated and viewed in an oscilloscope. The output was taken
from a standard 6 pin J5 connector. The output was taken from channel A of the DAC since
the output was delivered only to that channel. Extreme care and precaution was taken not to
short the Vcc and ground pins as well as any of the four channels to the ground. We could
generate an output voltage in the range of Dmin* Vref upto Dmax*Vref. But the output voltage
thus generated falls well within the limits as prescribed above. This is not true in the case of
sine wave. This action needs to performed to prevent the skewing of the signals at the peak
values. But the sine wave being curve, does not need the limit-setting action as mentioned
above since the skewing has relatively negligible effect for curved edges at the peak
5.2 Signal generation range.
As already mentioned before, we expected a maximum frequency of around 12.2
Khz for sine wave, 13.9 KHz for triangular wave and 2.8 KHz for ramp wave. The maximum
generated frequency too was very close to this value. The lowest frequency that was
generated was in the range of fraction of Hertz and very slow to be detected by the
oscilloscope. The square wave could be generated in the range of MHz. Therefore the probe
connecting the oscilloscope behaved as a filter and skewed the generated square wave at
higher frequencies. This required special high speed probes for testing which we acquired
from the RF lab.
5.3 Basic sample output
The sample output that was photographed was taken in a range that depicted perfect shapes
of Sine, Triangular, Ramp and square waves.
33
5.3.1 Sine Wave
Fig 5.1: Sine wave 11.27 Khz and 3.438 Vp-p(190 MHz master clock input)
5.3.2 Ramp wave
Fig 5.2: Ramp wave 2.584 Khz and 2.396 Vp-p(190 MHz master clock input)
34
5.3.3 Triangular Wave
Fig 5.3: Triangular wave 12.38 Khz and 2.469 Vp-p(190 MHz master clock input)
5.3.4 Square Wave
Fig 5.4: Square wave 125.8 KHz 3.500 Vp-p (1 MHz master clock input)
35
5.4 Sample outputs at varying amplitude and frequency
Sine wave(5.562 Vp-p 12.2 KHz) Triangular wave(5.812 Vp-p 12.16 KHz)
Fig 5.5 Outputs at varying amplitude and frequency
Square wave(6.187 Vp-p 12.27 KHz) Ramp wave(5.750 Vp-p 1.183 KHz)
36
CHAPTER 6
EPILOGUE
6.1 Cost analysis
SN Item Quantity Rate Amount
1 LM324 2 Rs 40 Rs 80
2 Potentiometer 2 Rs 15 Rs 30
3 Spartan 3E board 1 $ 150=Rs12000 Rs 12000
4 Miscellaneous Rs 100 Rs 100
Total Rs 12210
6.2 Problems faced and their solutions
i) Availability of the FPGA board
Even though we had designed our system long time ago we could not be sure of its
compatibility with the FPGA board that arrived much later. We had to make a lot of
changes in our design for it to work exactly in the Spartan 3E board. A very short time
was available for us to adapt to the board as well as interface external hardware.
ii) New type of DAC on offer
The DAC that was integrated inside the board was built on linear technology which
had quite difficult interfaces. The one that we are used to could simply tak parallel
data and convert it into an analogue output but in this DAC LTC2624 we had to
implement a separate module to interface with it. Another reason that restricted us
from using a conventional DACs was that they were very slow compared to the one
we had on board.
iii) Unfamiliarity with VHDL language and software bugs
We had to encounter many difficulties with the newest version of ISE which contain
many type of bugs. These bugs were evident when we tried to use the test bench.
37
Besides the VHDL language was itself a new one for us and quite different from the
conventional languages used for generating software.
6.3 Application
The signal generator we have implemented is especially helpful to the students who
require different types of signals for testing and experimentation purpose. The cost
of our project is not so high compared to the cost of a conventional signal generator
and we can synthesize much higher frequencies through embedded system
applications in FPGA. This is evident from the fact that we could synthesize square
waves accurately up to 200MHz. Much higher frequencies could still be generated but
without high speed probes, the synthesized high frequency could not be utilized. The
project can be purposeful especially in the fields of education and research, testing
and debugging of electronic circuits, communication and instrumentation Although
the limitation of DAC restricted us to synthesize higher frequencies of sine waves
,ramp wave and triangular wave ,this limitation can be eradicated using suitable type
of DAC.
6.4 Limitation
We could not meet our objectives of generating a continuous sine wave ,ramp wave
and triangular wave due to the high frequency noise present at lower frequencies. This
higher frequency noise could be removed using a suitable filter, however, the noise
had higher frequency values that change upon the changing of the clock pulse. So the
filter needed to have a variable cut-off frequency. The other limitation was due to the
DAC present on board. This could take data only serially and hence limited the
performance of our design. The duty cycle of the waves could not be varied. The
accuracy of the frequency of the wave although nominal could still be questioned. The
processing of the signal cannot be carried out at time periods less than one clock cycle
and hence we get a skew while generating signals where abrupt transitions are
required eg, ramp wave.
6.5 Recommendation and Conclusions
The project engrossed us and let us to believe in ourselves and helped us realized our
capabilities. The output we have extracted does not meet its end here. In the current
context, we can generate sine, triangular, ramp and square waves, but the frequency
38
on display in the LCD screen is only that of the square wave. Since this square wave
is of varying frequency and provided as a master clock to the sine, triangular and
ramp wave modules we can effectively vary the frequency of all types of waves
generated. The display of frequencies for other waves generated could be one of the
future enhancements. The amplitude of the waves generated can also be displayed but
require external input from the amplifier. The opamp that we have used cannot
support high frequency waves so we get a distortion of the signals while amplifying at
high frequencies. One of the opamps that can be suggested would be
AD9631/AD9632 which an effectively amplify high frequency waves. Another
limitation is generation of waves at much higher frequency as well as wave
generation at much higher input resolution. A higher speed DAC which takes in data
parallely can solve both these problems. One of such DAC that we found was
AD9726 which although supports clock only upto 15 MHz takes data in parallel. The
AD9913 DAC also comes handy as it has variety of inputs serial/parallel and could
perform conversions in the RF-range. Also the LTC1597 as well as LTC1591 are
DACs from the same manufacturer as the one present on the board could take in data
parallel while supporting the same clock frequency. This type of DAC comes in both
SSOP and PDIP packages and can be appropriate for different requirements of the
users. The current design can also be extended to generate specialized functions like
sinc functions, pulse trains,etc. This requires simple adjustments in the look up table
value of the sine wave. Finally the use of FPGA which is a new technology has
enhanced our familiarity with HDLs and made us easy for future adaptation in this
advanced field of embedded system.
39
References
1. Volnei A. Pedroni, Circuit Design with VHDL, MIT press, Cambridge Massachusetts
2. Douglas L. Perry, VHDL programming by example, Tata Mc Graw Hill
3. http://www.xilinx.com/support/documentation/spartan3e_board_and_kit_documentation.htm,
http://www.xilinx.com/support/documentation/boards_and_kits/ug230.pdf,
http://www.xilinx.com/s3estarter
http://www.xilinx.com/picoblaze
http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1155,C1005,C1156,P
2048,D2170
4. Xilinx ISE Design Suite 10.1 Software Manuals
ISE Quick Start Tutorial
Synthesis and Simulation Design Guide
Spartan-3E Libraries Guide for HDL Designs
40
APPENDIX
41
A1. ADDENDUMS
1. Documents
THE SQUARE WAVE GENERATING MODULE
Fig 1. Operating instruction for the square wave generating module
42
Fig 2. Diagrammatic flow of square wave generation process inside the FPGA
The square wave of exact frequency as displayed in the LCD can be generated with the help of the
design. The generated frequency as shown in the design flow consists of two variables. These
variables are N &D. The values of N & D can be synthesized using a simple picoblaze design as
illustrated in the next section. The changing values of N & D also means that there is a change in
synthesized output square wave frequency. This changing frequency signal can also act as a variable
clock pulse that appropriately changes the frequency of the signals generated from ramp, triangular
and sine wave generating module. The “sma_out” signal near the top most right of the diagram is the
43
synthesized variable clock frequency value. The generated square wave is accurate within a range of
1Hz to 200 MHz. This generated square wave frequency is thus suitable also for high frequency
applications.
Fig 3. Picoblaze circuit diagram for the generation of variables D &N.
This picoblaze design takes input from the user from the rotary encoder as well as input data from the
LCD screen in nibble mode. The data is passed through one of the input port of the picoblaze
microcontroller while The rotator pushbutton continuously generate interrupt signals to the picoblaze
processor. The oupput port value and the port id togethercontribute to generating a bidirectional data
for the LCD. Tha displays the frequency of the synthesized square wave in the LCD. This square
wave thus generatedhas a very low cycle to cycle jitter as explained in the figure itself.
44
PUSH BUTTON SWITCHES AND ROTARY ENCODERS
PUSH BUTTON SWITCHES
The Spartan-3E Starter Kit board has four momentary-contact push-button switches,
shown in Figure:. The push buttons are located in the lower left corner of the board and are
labeled BTN_NORTH, BTN_EAST, BTN_SOUTH, and BTN_WEST. The FPGA pins that
connect to the push buttons appear in parentheses in Figure:.
Fig 4. Push button locations in FPGA
All BTN_* push-button inputs require an internal pull-down resistor.
BTN_SOUTH is also used as a soft reset in some FPGA applications.
Way of operation of these switches
Pressing a push button connects the associated FPGA pin to 3.3V, as shown in Figure:.
Use an internal pull-down resistor within the FPGA pin to generate a logic Low when the
button is not pressed. There is no active debouncing circuitry on the push button.
45
Fig 5. Push button switches in operation
ROTARY PUSH-BUTTON SWITCH
The rotary push-button switch is located in the center of the four individual push-button
switches, as shown in Figure:. The switch produces three outputs. The two shaft encoder
outputs are ROT_A and ROT_B. The center push-button switch is ROT_CENTER.
Fig 6. Rotary Push button switches in operation
Operation of this switch
The rotary push-button switch integrates two different functions. The switch shaft rotates
and outputs values whenever the shaft turns. The shaft can also be pressed, acting as a push-
button switch.Push-Button SwitchPressing the knob on the rotar.
Push-Button Switch
Pressing the knob on the rotary/push-button switch connects the associated FPGA pin to
3.3V, as shown in Figure:. Use an internal pull-down resistor within the FPGA pin to
generate a logic Low. There is no active debouncing circuitry on the push button.
46
Rotary Shaft Encoder
The rotary shaft encoder behaves much like a cam, connected to central shaft. Rotating the
shaft then operates two push-button switches, as shown in Figure:. Depending on which way
the shaft is rotated, one of the switches opens before the other. Likewise, as the rotation
continues, one switch closes before the other. However, when the shaft is stationary, also
called the detent position, both switches are closed.
Fig 7. Push shaft encoders in operation
Closing a switch connects it to ground, generating a logic Low. When the switch is open, a
pull-up resistor within the FPGA pin pulls the signal to a logic High. The UCF constraints in
Figure2-9 describe how to define the pull-up resistor.The FPGA circuitry to decode the „A‟
and „B‟ inputs is simple, but must consider the mechanical switching noise on the inputs, also
called chatter. As shown in Figure:, the chatter can falsely indicate extra rotation events or
even indicate rotations in the opposite direction.
Fig 8. Timing diagrams of rotary shaft encoders
47
CHARACTER LCD SCREEN
The Spartan-3E Starter Kit board prominently features a 2-line by 16-character liquid
crystal display (LCD). The FPGA controls the LCD via the 4-bit data interface shown in
Figure:. Although the LCD supports an 8-bit data interface, the Starter Kit board uses a 4-bit
data interface to remain compatible with other Xilinx development boards and to minimize
total pin count.
Fig 9. character LCD interface
Once mastered, the LCD is a practical way to display a variety of information using
standard ASCII and custom characters. However, these displays are not fast. Scrolling the
display at half-second intervals tests the practical limit for clarity. Compared with the 50MHz
clock available on the board, the display is slow. A PicoBlaze processor efficiently controls
display timing plus the actual content of the display.
48
Table 1: Interface character LCD interface signals
The character LCD is power by +5V. The FPGA I/O signals are powered by 3.3V. However,
the FPGA‟s output levels are recognized as valid Low or High logic levels by the LCD. The
LCD controller accepts 5V TTL signal levels and the 3.3V LVCMOS outputs provided by
the FPGA meet the 5V TTL voltage level requirements. The 390Ω series resistors on the data
lines prevent overstressing on the FPGA and StrataFlash I/O pins when the character LCD
drives a High logic value. The character LCD drives the data lines when LCD_RW is High.
Most applications treat the LCD as a write-only peripheral and never read from from the
display.
Interaction with Intel StrataFlash
As shown in Figure:, the four LCD data signals are also shared with StrataFlash data lines
SF_D<11:8>. As shown in Table:, the LCD/StrataFlash interaction depends on the
application usage in the design. When the StrataFlash memory is disabled (SF_CE0 = High),
then the FPGA application has full read/write access to the LCD. Conversely, when LCD
read operations are disabled (LCD_RW = Low), then the FPGA application has full
read/write access to the StrataFlash memory.
49
Table 2. Strata flash interface signals with LCD
„X‟ indicates a don‟t care, can be either 0 or 1.
CLOCK SOURCES IN FPGA
The Spartan-3E Starter Kit board supports three primary clock input sources, all of which
are located below the Xilinx logo, near the Spartan-3E logo.
• The board includes an on-board 50MHz clock oscillator.
• Clocks can be supplied off-board via an SMA-style connector. Alternatively, the
FPGA can generate clock signals or other high-speed signals on the SMA-style
connector.
• Optionally install a separate 8-pin DIP-style clock oscillator in the supplied socket.
The clock sources of the board have been shown in the figure:.
Fig 10. Clock locations in FPGA board
50
50 MHz On-Board Oscillator
The board includes a 50 MHz oscillator with a 40% to 60% output duty cycle. The
oscillator is accurate to ±2500 Hz or ±50 ppm.
Auxiliary Clock Oscillator Socket
The provided 8-pin socket accepts clock oscillators that fit the 8-pin DIP footprint. Use
this socket if the FPGA application requires a frequency other than 50 MHz. Alternatively,
use the FPGA‟s Digital Clock Manager (DCM) to generate or synthesize other frequencies
from the on-board 50 MHz oscillator
SMA Clock Input or Output Connector
To provide a clock from an external source, connect the input clock signal to the SMA
connector. The FPGA can also generate a single-ended clock output or other high-speed
signal on the SMA clock connector for an external device.
Slide Switches Locations and Labels
The Spartan-3E Starter Kit board has four slide switches, as shown in Figure 2-1. The slide
switches are located in the lower right corner of the board and are labeled SW3 through
SW0. Switch SW3 is the left-most switch, and SW0 is the right-most switch.
Fig 11. Slide switches locations Operation
When in the UP or ON position, a switch connects the FPGA pin to 3.3V, a logic High.
When DOWN or in the OFF position, the switch connects the FPGA pin to ground, a logic
Low. The switches typically exhibit about 2 ms of mechanical bounce and there is no active
debouncing circuitry, although such circuitry could easily be added to the FPGA design
programmed on the board.
51
52
2. Datasheets
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
A2. SOURCE CODES
1. The triangular wave generating module
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity triwv is
port(
clk: in std_logic;
enable: in std_logic;
reset: in std_logic;
wavot: out std_logic_vector(11 downto 0)
);
end triwv;
architecture behav of triwv is
type state is (count_up, count_down);
signal pstate,nstate: state;
signal temp: std_logic_vector(11 downto 0):="000011001000";
begin
process(clk, reset)
begin
if(reset='1') then
pstate<=count_up;
-- wavot<="000000000000";
elsif(clk'event and clk='1') then
if(enable='1')then
pstate<=nstate;
end if;
end if;
end process;
process(pstate,temp)
begin
nstate<=pstate;
case pstate is
when count_up=>
if temp>=3000 then
nstate<=count_down;
end if;
when count_down=>
68
if temp<200 then
nstate<=count_up;
end if;
end case;
end process;
process(clk,reset)
begin
if reset='1' then
temp<="000011001000";
elsif(clk'event and clk='1') then
if enable='1' then
case nstate is
when count_up=>
temp<=temp+100;
when count_down=>
temp<=temp-100;
end case;
end if;
end if;
wavot<=temp;
end process;
end behav;
2. The ramp wave generating module
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity rmpwv is
port(
clk: in std_logic;
enable: in std_logic;
reset: in std_logic;
datout: out std_logic_vector(11 downto 0)
);
end rmpwv;
architecture perf of rmpwv is
signal temp: std_logic_vector(11 downto 0):="000011001000";
begin
process(clk)
begin
69
if(enable='0')then
temp<=temp;
elsif(reset='1')then
temp<="000011001000";
elsif(clk'event and clk='1') then
temp<=temp+10;
if(temp>=3000) then
temp<="000011001000";
end if;
end if;
datout<=temp;
end process;
end perf;
3. Sine wave generating module
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.sine_package.all;
entity sine_wave is
port( clock, reset, enable: in std_logic;
wave_out: out sine_vector_type);
end;
architecture arch1 of sine_wave is
type state_type is ( counting_up, change_down, counting_down, change_up );
signal state, next_state: state_type;
signal table_index,table_index_1: table_index_type;
signal positive_cycle: boolean;
begin
process( clock, reset )
begin
if reset = '1' then
state <= counting_up;
elsif rising_edge( clock ) then
if enable = '1' then
state <= next_state;
end if;
end if;
end process ;
process( state, table_index )
begin
next_state <= state;
case state is
when counting_up =>
if table_index = max_table_index or table_index_1=max_table_index then
next_state <= change_down;
70
end if;
when change_down =>
next_state <= counting_down;
when counting_down =>
if table_index = 0 then
next_state <= change_up;
end if;
when others => -- change_up
next_state <= counting_up;
end case;
end process;
process( clock, reset )
begin
if reset = '1' then
table_index <= 0;
table_index_1 <= 0;
positive_cycle <= true;
elsif rising_edge( clock ) then
if enable = '1' then
case next_state is
when counting_up =>
table_index <= table_index + 1;
table_index_1 <= table_index_1 + 1;
when counting_down =>
table_index <= table_index - 1;
table_index_1 <= table_index_1 - 1;
when change_up =>
positive_cycle <= not positive_cycle;
when others =>
-- nothing to do
end case;
end if;
end if;
end process;
process( table_index,table_index_1, positive_cycle )
variable table_value: table_value_type;
variable table_value_1: table_value_type;
begin
table_value := get_table_value( table_index );
table_value_1 := get_table_value_1( table_index_1 );
if positive_cycle then
wave_out <= std_logic_vector(to_unsigned(table_value,sine_vector_type'length)+2048);
else
-- wave_out <= std_logic_vector(to_signed(-table_value,sine_vector_type'length));
wave_out <= std_logic_vector(to_unsigned(table_value_1,sine_vector_type'length));
end if;
71
end process;
end;
4. Sine package:- Contains table values for the sine wave generating module
library ieee;
use ieee.std_logic_1164.all;
package sine_package is
constant max_table_value: integer := 2047;
subtype table_value_type is integer range 0 to max_table_value;
constant max_table_index: integer := 15;
subtype table_index_type is integer range 0 to max_table_index;
subtype sine_vector_type is std_logic_vector( 11 downto 0 );
function get_table_value (table_index: table_index_type) return table_value_type;
function get_table_value_1 (table_index_1: table_index_type) return table_value_type;
end;
package body sine_package is
function get_table_value (table_index: table_index_type) return table_value_type is
variable table_value: table_value_type;
begin
case table_index is
when 0 =>
table_value := 100;
when 1 =>
table_value := 300;
when 2 =>
table_value := 497;
when 3 =>
table_value := 690;
when 4 =>
table_value := 875;
when 5 =>
table_value := 1052;
when 6 =>
table_value := 1219;
when 7 =>
table_value := 1375;
when 8 =>
table_value := 1517;
when 9 =>
table_value := 1644;
when 10 =>
table_value := 1756;
when 11 =>
table_value := 1850;
when 12 =>
table_value := 1927;
when 13 =>
72
table_value := 1986;
when 14 =>
table_value := 2025;
when 15 =>
table_value := 2045;
end case;
return table_value;
end;
function get_table_value_1 (table_index_1: table_index_type) return table_value_type is
variable table_value_1: table_value_type;
begin
case table_index_1 is
when 0 =>
table_value_1 := 1948;
when 1 =>
table_value_1 := 1748;
when 2 =>
table_value_1 := 1551;
when 3 =>
table_value_1 := 1358;
when 4 =>
table_value_1 := 1173;
when 5 =>
table_value_1 := 996;
when 6 =>
table_value_1 := 829;
when 7 =>
table_value_1 := 673;
when 8 =>
table_value_1 := 531;
when 9 =>
table_value_1 := 404;
when 10 =>
table_value_1 := 292;
when 11 =>
table_value_1 := 198;
when 12 =>
table_value_1 := 121;
when 13 =>
table_value_1 := 62;
when 14 =>
table_value_1 := 23;
when 15 =>
table_value_1 := 3;
end case;
return table_value_1;
end;
73
end;
5. Module for communicating triangular wave generating module with the SPI
interface inside the DAC
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spicom is
Port ( sin_ip : in STD_LOGIC_VECTOR (11 downto 0);
clk,load : in STD_LOGIC;
sdi : out STD_LOGIC;
dac_cs : out STD_LOGIC;
ack : out STD_LOGIC:='0';
dac_clr : out STD_LOGIC :='1';
clk1: out STD_LOGIC);
end spicom;
architecture Behavioral of spicom is
signal tmp : STD_LOGIC_VECTOR (31 DOWNTO 0);
signal tx : integer range 0 to 31 :=0;
begin
process(clk)
begin
if(clk'event and clk='1') then
if(load='1')then
dac_cs<='0';
tx<=0;
ack<='0';
tmp(15 downto 4)<=sin_ip;
tmp(19 downto 16)<="0000";
tmp(23 downto 20)<="0011";
tmp(3 downto 0)<="0000"; --dont care
tmp(31 downto 24)<="00000000"; --dont care
elsif(tx>30) then
dac_cs<='1';
ack<='1';
tx<=0;
else
dac_cs<='0';
ack<='0';
tmp<=tmp(30 downto 0) & '0';
tx<=tx+1;
end if;
end if;
end process;
74
clk1<=clk;
sdi <=tmp(31);
end Behavioral;
6. Module for communicating sine and ramp wave generating module with the
SPI interface inside the DAC
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spicom1 is
Port ( sin_ip1 : in STD_LOGIC_VECTOR (11 downto 0);
clk1,load1 : in STD_LOGIC;
sdi1 : out STD_LOGIC;
dac_cs1 : out STD_LOGIC;
ack1 : out STD_LOGIC:='0';
dac_clr1 : out STD_LOGIC :='1'
-- clk1: out STD_LOGIC
);
end spicom1;
architecture Behavioral of spicom1 is
signal tmp : STD_LOGIC_VECTOR (31 DOWNTO 0);
signal tx : integer range 0 to 31 :=0;
begin
process(clk1)
begin
if(clk1'event and clk1='1') then
if(load1='1')then
dac_cs1<='0';
tx<=0;
ack1<='0';
tmp(15 downto 4)<=sin_ip1;
tmp(19 downto 16)<="0000";
tmp(23 downto 20)<="0011";
tmp(3 downto 0)<="0000"; --dont care
tmp(31 downto 24)<="00000000"; --dont care
elsif(tx>30) then
dac_cs1<='1';
ack1<='1';
tx<=0;
-- elsif(tx<1) then
-- dac_cs<='1';
-- ack<='0';
else
dac_cs1<='0';
ack1<='0';
tmp<=tmp(30 downto 0) & '0';
75
tx<=tx+1;
end if;
end if;
end process;
--clk1<=clk;
sdi1 <=tmp(31);
end Behavioral;
7. Unit for multiplexing signals to the DAC
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity spimulplx is
Port (
d_cs_tri : in STD_LOGIC;
sd_tri : in STD_LOGIC;
d_clr_tri : in STD_LOGIC;
d_cs_rmp : in STD_LOGIC;
sd_rmp : in STD_LOGIC;
d_clr_rmp : in STD_LOGIC;
d_cs_sin : in STD_LOGIC;
sd_sin : in STD_LOGIC;
d_clr_sin : in STD_LOGIC;
btn_tri : in STD_LOGIC;
btn_rmp : in STD_LOGIC;
btn_sin : in STD_LOGIC;
d_cs_out : out STD_LOGIC;
sd_out : out STD_LOGIC;
d_clr_out : out STD_LOGIC);
end spimulplx;
architecture Behavioral of spimulplx is
signal d_cs_tmp, sd_tmp: std_logic:='0';
signal d_clr_tmp: std_logic:='1';
begin
process(btn_tri,btn_sin,btn_rmp,d_cs_tri,sd_tri,d_clr_tri,d_cs_sin,sd_sin,d_clr_sin,d_cs_rmp,s
d_rmp,d_clr_rmp)
begin
if( btn_sin='1')then
d_cs_tmp<=d_cs_sin;
sd_tmp<=sd_sin;
d_clr_tmp<=d_clr_sin;
elsif(btn_tri='1')then
d_cs_tmp<=d_cs_tri;
sd_tmp<=sd_tri;
76
d_clr_tmp<=d_clr_tri;
elsif(btn_rmp='1')then
d_cs_tmp<=d_cs_rmp;
sd_tmp<=sd_rmp;
d_clr_tmp<=d_clr_rmp;
else
d_cs_tmp<='0';
sd_tmp<='0';
d_clr_tmp<='1';
end if;
end process;
d_cs_out <=d_cs_tmp;
sd_out<= sd_tmp;
--clkot_out<=clkot_tmp;
d_clr_out<=d_clr_tmp;
end Behavioral;
8. Unit for interconnection of all the modules mentioned above
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.sine_package.all; entity conn is Port ( clock : in STD_LOGIC; reset : in STD_LOGIC; but1,but2,but3: in STD_LOGIC; d_clr : out STD_LOGIC:='1'; d_cs : out STD_LOGIC; sd : out STD_LOGIC; clkot: out STD_LOGIC; sineout : out sine_vector_type; rmpout : out sine_vector_type; triout : out sine_vector_type ); end conn; architecture Behavioral of conn is component sine_wave is port( clock, reset, enable: in std_logic; wave_out: out sine_vector_type); end component; component rmpwv is port( clk: in std_logic; reset: in std_logic; enable: in std_logic; datout: out std_logic_vector(11 downto 0)); end component; component triwv is port( clk: in std_logic;
77
reset: in std_logic; enable: in std_logic; wavot:out std_logic_vector(11 downto 0) ); end component; component spicom1 is Port ( sin_ip1 : in STD_LOGIC_VECTOR (11 downto 0); clk1,load1 : in STD_LOGIC; sdi1 : out STD_LOGIC; dac_cs1 : out STD_LOGIC; ack1 : out STD_LOGIC:='0'; dac_clr1 : out STD_LOGIC :='1' -- clk1: out STD_LOGIC ); end component; component spicom is Port ( sin_ip : in STD_LOGIC_VECTOR (11 downto 0); clk,load: in STD_LOGIC; sdi: out STD_LOGIC; dac_cs: out STD_LOGIC; ack: out STD_LOGIC; dac_clr: out STD_LOGIC; clk1: out STD_LOGIC ); end component; component spimulplx is Port ( -- clock : in STD_LOGIC; d_cs_tri : in STD_LOGIC; sd_tri : in STD_LOGIC; -- clkot_tri : in STD_LOGIC; d_clr_tri : in STD_LOGIC; d_cs_rmp : in STD_LOGIC; sd_rmp : in STD_LOGIC; -- clkot_rmp : in STD_LOGIC; d_clr_rmp : in STD_LOGIC; d_cs_sin : in STD_LOGIC; sd_sin : in STD_LOGIC; -- clkot_sin : in STD_LOGIC; d_clr_sin : in STD_LOGIC; btn_tri : in STD_LOGIC; btn_rmp : in STD_LOGIC; btn_sin : in STD_LOGIC; d_cs_out : out STD_LOGIC; sd_out : out STD_LOGIC; -- clkot_out : out STD_LOGIC; d_clr_out : out STD_LOGIC); end component; signal d_cs_1: std_logic; signal sd_1: std_logic; signal clkot_1:std_logic; signal d_clr_1: std_logic; signal d_cs_2: std_logic; signal sd_2: std_logic;
78
--signal clkot_2:std_logic; signal d_clr_2: std_logic; signal d_cs_3: std_logic; signal sd_3: std_logic; --signal clkot_3:std_logic; signal d_clr_3: std_logic; signal wav_ot: std_logic_vector(11 downto 0); signal x1,x2,x3: std_logic; --enables signal y1,y2,y3: std_logic_vector(11 downto 0); begin U1: triwv port map(clock,reset,x1,y1); U2: rmpwv port map(clock,reset,x2,y2); U3: sine_wave port map(clock,reset,x3,y3); U4: spicom port map(y1,clock,x1,sd_1,d_cs_1,x1,d_clr_1,clkot_1); U5: spicom1 port map(y2,clock,x2,sd_2,d_cs_2,x2,d_clr_2); U6: spicom1 port map(y3,clock,x3,sd_3,d_cs_3,x3,d_clr_3); U7: spimulplx port map(d_cs_1,sd_1,d_clr_1,d_cs_2,sd_2,d_clr_2,d_cs_3,sd_3,d_clr_3,but1,but2,but3,d_cs,sd,d_clr); clkot<=clkot_1; sineout<=y3; rmpout<=y2; triout<=y1; end Behavioral;
9. Unit for dividing the input clock eight times library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity freqdiv is -- generic (ipnx: std_logic_vector(4 downto 0):="11010"); port( -- ipnx: std_logic_vector(4 downto 0); clkin: in std_logic; clkout: out std_logic ); end freqdiv; architecture performance of freqdiv is signal temp: std_logic:='0'; signal temp1: std_logic_vector(4 downto 0):="00000"; begin process(clkin) begin if(clkin'event and clkin='1') then temp1<=temp1+1; if(temp1>"00010") then temp<=not temp; temp1<="00000"; end if; end if; clkout<=temp; end process; end performance;