design of an ethernet-based public address system … · design of an ethernet-based public address...
TRANSCRIPT
See discussions, stats, and author profiles for this publication at: https://www.researchgate.net/publication/235929509
Design of an Ethernet-based Public Address System Using Xilinx SPARTAN™-3E
Starter Board
Thesis · April 2008
CITATIONS
0
READS
1,308
3 authors, including:
Some of the authors of this publication are also working on these related projects:
Application of Swarm Intelligence to Smart Grids View project
Clean Energy Project Analysis View project
Ryan Tulabing
University of Auckland
4 PUBLICATIONS 8 CITATIONS
SEE PROFILE
All content following this page was uploaded by Ryan Tulabing on 16 May 2014.
The user has requested enhancement of the downloaded file.
Design of an Ethernet-based Public
Address System Using Xilinx
SPARTAN™-3E Starter Board
By:
Ryan S. Tulabing
Jamela Q. Macarimbang
Junrey O. Ansing
Advisers:
Engr. Sihawi A. Khalid
Engr. Karla M. Madrid
Mindanao State University-Main Campus
Mindanao State University
College of Engineering
Electrical and Electronics Department
Marawi City
ii
APPROVAL SHEET
In partial fulfillment of the requirements for the degree of Bachelor of Electrical
Engineering, this project entitled: “DESIGN OF AN ETHERNET BASED PUBLIC
ADDRESS SYSTEM USING XILINX SPARTAN™-3E STARTER BOARD”, has been
prepared and submitted by Ryan S. Tulabing and Jamela Q. Macarimbang who are
recommended for oral defense.
Engr. Karla M. Madrid Engr.Sihawi A. Khalid
Adviser Adviser
Approved by the Electrical and Electronics Engineering Department Panel for Oral
Examination with a grade of _____.
________________ __________________
Member Member
________________
Member
Accepted in partial fulfillment of the requirement for the Course EE199 (Undergraduate
Project)
Engr. Karla M. Madrid
Chairperson, EEE Department
iii
Abstract
Several studies had been conducted on the development of Ethernet-based Public
Addressing Systems (EPAS) to multicast real time audio towards a network of speakers
using personal computers and/or microcontrollers. This project presents a design for an
Ethernet-based public address system (EPAS) using a personal computer and the Xilinx
Spartan™-3E Starter Board as end points. The system, which will be used to broadcast
voice announcements to (a network of) audio speakers through any existing Local Area
Network (LAN), can be employed in any public establishment such as cafeterias,
airports, shopping malls and similar places.
A software application is developed to packet audio signals from an input
microphone and to transmit the data using Ethernet protocols over an existing LAN to the
FPGA receiver. The FPGA receiver is programmed to receive and decode data packets,
convert digital data back to analog to be used to drive external audio speakers. This
project primarily aims to demonstrate Voice over IP (VoIP) using an FPGA receiver. By
using a PC at one end and an FPGA at the receiving end, this project is used to
demonstrate data communication principles (VoIP) and promote understanding of the
differences between software and hardware implementations of embedded systems
applications for data communications.
iv
Acknowledgement
I, Jam would like to extend my heartfelt gratitude to the people who helped and
encouraged me as we did this thesis.
I thank my father and mother for their support financially. I thank them for buying
me a computer which I used for this project. I thank them for taking care of me while I
was sick because of stress. I thank my younger brother and sister, for their helped while I
was testing the sender module.
I thank my nanay’s or ate’s: ate Marvey, ate Mai and ate Swen, for their
encouragement all throughout. I thank them for I can run to them whenever I want to cry
because of disappointment. I thank them for I learned from them how to respond on each
life’s trials and challenges. I thank them for the love that they have shown me.
I thank my best friend, Aznia Azineth for cheering me up whenever I feel upset.
Because when I was doing the thesis there are many times that I’ve been disappointed
because of the results and the response of people. I thank her for I can lean on her, for
being my comrade. “Thanks Az”.
I thank our advisers: Sir Khalid and Maam Karla, for the technical guidance, for
editing our papers and helping us with our presentation and teaching us how to present it.
I thank God, for your lives and the knowledge that you share to us.
I thank Kuya Julieto for being patient with us, for allowing us to stay late in the
college. Thanks also to the EEE people, our instructors and to all who have helped us.
Above all, I thank the Lord Isah Almasih for the wisdom and sustaining me with
strength, providing all my needs. I thank Him for the comfort and the assurance that
comes from Him. I thank Him for the success of this project. I thank Him for intervening
and making a way for us that we may be able to present this project “despite the
distance”.
v
Acknowledgement
Dear God,
I thank You for sending me the following persons who helped me directly or indirectly in
gaining this achievement.
Sir Sihawi Khalid and Ma’am Karla Madrid, our brilliant advisers who patiently assisted us all throughout the project. They taught us not only the technical knowledge but most
importantly, the attitude towards work. Together with the faculties and staffs of the EEE
department and the College of Engineering as a whole they molded me to be a globally
competitive Electrical Engineer. Thus, whatever success I may gain in the future, I owe it from my noble instructors whom I will always acknowledge for the next chapters of my career.
My colleagues, especially Jamela Macarimbang and Junrey Ansing whom I worked
with in doing this thesis. Indeed they taught me how to work on a team and trust other people with their abilities.
My Parents, who generously gave their undying support not only financially but more on
the spiritual and moral aspects. I could feel their love and their answered prayers despite the distance. May You lengthen their lives and keep them healthy and satisfied.
My brother, Reinan, who helped me indirectly by doing my other responsibilities and
works in my behalf, which gave me extra time to work on this project.
My second family in MSU, the Miñoza and Franco Family: They have given me space in their homes and let me borrow some of their equipments (i.e. PC, printer… etc) to finish my
project on time. They also have given me a space in their hearts as a friend and as a family that I
could feel the warmth of their love and concern on the delicious food we eat together and the way they make me laugh and motivate me to do better. They made my stay here in MSU a lot more
comfortable.
My Friends, the MSU-SDA family, especially the RAYS who believed in the talents that
You have bestowed upon us. With them I grew more mature and improved my leadership skills as we offer our talents and gifts back to You.
The special person in my life who listens to my frustrations, comforts, and encourages me
whenever I feel tired and disappointed with the outcome of my endeavors. She keeps on motivating me to reach the top and reach my goals in life for a brighter future…Argie.
Lord, thank you for everyone who helped including those which I failed to mention. Please continue blessing them and always keep them under your wings.
Whatever may our plans are, if it is thine will, let it be done. If it’s not, then help us
understand and accept it.
All the Glory and All the Honor shall be unto You…
Sincerely Yours,
Ryan
vi
TABLE OF CONTENTS
Title Page…………………………………………………………………………... i
Approval Sheet………………………………………………. ……………………. ii
Abstract…………………………………………………………………………….. iii
Acknowledgement……………………………………………………………......... iv
Table of Contents…………………………………………………………………... vi
List of Figures……………………………………………………………………… viii
List of Tables………………………………………………………………………. ix
Chapter 1…………………………………………………………………………… 1
INTRODUCTION…………………………………………………………. 1
Chapter 2 .....................................................................…………………………….. 3
REVIEW OF RELATED THEORY AND TECHNOLOGY……………... 3
Pulse Code Modulation…………………………………………………….. 3
User Datagram Protocol……………………………………………………. 3
Ethernet 802.3 Standard……………………………………………………. 3
Broadcasting……………………………………………………………….. 3
Field Programmable Gate Array…………………………………………… 4
Companding………………………………………………………………... 4
Chapter 3………………………………………………………………………........ 5
DESIGN AND IMPLEMENTATION…...................................................... 5
SYSTEM OVERVIEW……………………………………………………. 5
DETAILED SPECIFICATIONS…………………………………………… 6
PROCESSES AND ALGORITHMS……………………………………..... 7
SENDER MODULE………………………………………………............. 7
RECEIVER MODULE………..…………………………………………… 10
Start of the Frame Delimiter………………………………….......... 14
Address Matching Logic........……………………………………… 16
Buffer………………………………………………………………. 19
Digital to Analog Conversion…………………………………........ 21
vii
PROCEDURE FOR SETTING UP THE SYSTEM………………………… 28
TESTS AND RESULTS…………………………………………………… 29
Chapter 4…………………………………………………………………………… 32
CONCLUSIONS AND RECOMMENDATIONS………………………… 32
REFERENCES…………………………………………………………………….. 34
APPENDIX A: HDL DESCRIPTIONS…………………………………………… 36
APPENDIX B: TESTBENCHES………………………………………………….. 58
APPENDIX C: CONSTRAINT FILES……………………………………………. 72
APPENDIX D: DELPHI SOURCE CODES………………………………………. 73
viii
LIST OF FIGURES
Figure 2.1 System Overview ………………………………………………………. 5
Figure 2.2 EPAS Configuration …………………………………………………… 6
Figure 2.3 Sender Module Flow Chart ……………………………...…………….. 7
Figure 2.4 EPAS Sender Module ………………………………………………….. 8
Figure 2.5 Data Encapsulation …………………………………………………….. 9
Figure 2.6 Format of the Packet …………………………………………………… 9
Figure 2.7a Block Diagram of Data flow in the Receiver…………………………. 10
Figure 2.7b Block Diagram of FPGA Receiver Module ………………………….. 11
Figure 2.8 Parts of the Received Packet …………………………………………... 12
Figure 2.9 Receiver Flow Chart …………………………………………………… 13
Figure 2.10 SFD Block Diagram ………………………………………………….. 14
Figure 2.11 SFD Algorithm ……………………………………………………….. 15
Figure 2.12 AML Block Diagram …………………………………………………. 16
Figure 2.13 Address Matching Logic Flow Diagram ……………………………... 17
Figure 2.14 Address Matching Logic Process ………………………….................. 18
Figure 2.15 RAM: [192: 8] ………………………………………………….…….. 19
Figure 2.16 Buffer flow ……………………………………………………….…... 21
Figure 2.17 Interconnection between the FPGA and the DAC …………………… 21
Figure 2.18 DAC clock relationships ………………………………………………22
Figure 2.19 DAC input data ……………………………………………………….. 22
Figure 2.20 DAC Clock derivation algorithm..……………………………………. 22
Figure 2.21 Digital to Analog Converter Summary………………………………... 27
Figure 2.22 EPAS System Set Up…………………………………………………. 28
ix
LIST OF TABLES
Table 2.1 Receiver Module Signals ……………………………………………….. 11
Table 2.2 SFD Module Signals…………………………………………………….. 14
Table 2.3 AML Module Signals ……………………………………………….…... 16
1
Chapter 1
Introduction
A Public Addressing System is a very useful communication tool in large,
crowded establishments such as airports, train stations, shopping centers, business
buildings, school campuses and many others. With this system, public announcements
and other information are effectively disseminated from audio speakers located at the
strategic positions within the establishment.
Traditional Public Addressing Systems consisted of microphone inputs and audio
speakers interconnected by hard wires. With rapid developments in computer networking
technologies and the integration of voice, video, and data in multiple applications, any
existing Ethernet LAN can be used as a backbone for a public address system. Utilizing
any established network minimizes the need for additional wires and cables necessary for
a separate public address system, consequently minimizing labor and cost. Although
these advantages can be achieved by using a PC-to-PC system, it is impractical and quite
expensive to purchase a whole lot of computers for the real-time audio reception. An
alternative device that is dedicated to receiving voice packets and driving external audio
speakers is sought using Field Programmable Gate Arrays (FPGA). An FPGA board is
cheaper compared to personal computer and consumes lesser power. In addition, using a
dedicated component (FPGA) for receiving and driving the speakers will enable the
EPAS to work independently from the rest of the network.
This project presents a design for an Ethernet-based public address system
(EPAS)using a personal computer and the Xilinx Spartan™-3E Starter Board as end
points. The system, which will be used to broadcast voice announcements to (a network
of) audio speakers through any existing Local Area Network (LAN), can be employed in
any public establishment such as cafeterias, airports, shopping malls and similar places.
By using a PC at one end and an FPGA at the receiving end, this project
effectively demonstrates data communication principles (VoIP) and promotes
understanding of the differences between software and hardware implementations of
embedded systems applications for data communications. The proposed Ethernet-based
Public Addressing System makes use of Ethernet 802.3 standard that enables many hosts
2
to transmit and receive data over a twisted pair network. The project has three main
components: the server/transmitter (PC), the LAN backbone, and the receiver (FPGA).
Details of these components are discussed in the succeeding chapters.
3
Chapter 2
Review of Background Theory and Technology
2.1 Pulse Code Modulation (PCM)
Pulse Code Modulation, is the most common technique to convert an analog
signal to a digital signal. PCM has been used in digital telephone systems and is also the
standard form for digital audio in computers and the compact disc red book format [22].
In this project Mono8Bit48000 Hz was chosen for the Broadcaster program. This
is so, because the human voice is of Mono type. It uses only one independent channel
source [23].
2.2 User Datagram Protocol (UDP)
UDP or the User Datagram Protocol is a best-effort transport standard that is
layered on the IP protocol. UDP has no flow control mechanism or reliable delivery and
simply employs queues to store incoming messages. These shortcomings make it ideal
for real-time transmissions such as media streams where on-time delivery carries a higher
priority than bit-correctness. UDP processes employ ports to indirectly identify each
other and often make use of known, reserved addresses on a per application basis [21].
2.3 Ethernet 802.3 Standard
Ethernet/IEEE802.3 standard enables many hosts to transmit and receive data
over a twisted pair network. The 802.3 Ethernet Standard was drafted in 1983 by the
Institute of Electrical and Electronic Engineers (IEEE). Originally developed in the early
1970s by members of the Xerox Palo Alto Research Centre, it interconnected computers
and laser printers at a speed of 2.94 Mb/s. Several years (and revisions) on, Ethernet has
gained features such as collision detection and has emerged as the definitive standard for
general purpose networks [21].
2.4 Broadcasting
Broadcasts are useful when a host needs to find information without knowing
exactly what other host can supply it, or when a host wants to provide information to a
large set of hosts in a timely manner [3]. Broadcasting is shouting to the wind. A
datagram (packet) is put on the wire with an address that tells all machines to pick it up
and carry it to the socket level.
4
2.5 Field Programmable Gate Array (FPGA)
FPGA‟s are programmable digital logic chips. They can be programmed to do
almost any digital function. When working with FPGA‟s: A computer is used to describe
a "logic function" that you want. A schematic or a text file describing the function is first
made. Then this logic function is compiled in a computer, using software provided by the
FPGA vendor that creates a binary file that can be downloaded into the FPGA. A cable is
then connected from the computer to the FPGA and then downloads the binary file to the
FPGA. The FPGA then behaves according to the “logic function” [24].
2.6 Companding
Companding is the process of compressing and expanding. With companded
systems, the higher amplitude analog signals are compressed prior to transmission and
then expanded in the receiver. Companding is a means of improving the dynamic range
of communication systems [25]. In this project we make use of the mu-law companding.
5
Chapter 3
Design and Implementation
3.1 System Overview
Figure 2.1: System Overview
Figure 2.1 above illustrates the set-up of the Ethernet-based Public Addressing
System. Audio signals from the microphone is fed into and processed by the personal
computer (PC). Processing involves analog-to-digital conversion i.e. linear PCM coding
of the analog audio and packetization or encapsulation of the audio data. The voice
packets are then sent out through the Network Interface Card of the PC to the Local Area
Network (LAN). Over the Ethernet, the audio packets are sent through the router to the
FPGA receiver connected to the LAN through its onboard RJ45 connector. The FPGA
board then performs de-packetization and conversion of the voice packets back to analog
signals using its onboard digital-to-analog converter (DAC). Finally, the output analog
signal is amplified and used to drive the speakers.
6
3.2 Detailed Specifications
Figure 2.2: EPAS Configuration
The Ethernet-based Public Addressing System uses a personal computer (PC)
connected to the Local Area Network that serves as the central server. A microphone,
connected to the microphone jack of the PC audio card (on board or PCI connected)
serves as input. To make voice announcements, a user employs the software application
called Sender Module on the PC server. This module displays information such as the
Host name of the PC server, its IP address, Port and Destination addresses and the total
buffer size, i.e. the total bytes sent to the network. Two buttons labeled Start and Stop
enable the user to begin and end transmission of voice data. The FPGA board,
specifically Xilinx Spartan™-3E Development Board, also connected to the LAN
through its RJ45 connector, acts as the receiver. Audio speakers connected to the board
serves as output.
Microphone
Speakers
Analog Signal
Analog Signal
PC - Sender
FPGA - Receiver
Packets data
Packets data
Local Area Network
7
3.3 Processes and Algorithms
This project was subdivided into two main components: the Sender Module and
the Receiver Module. Both components were developed simultaneously. Details are
discussed in the succeeding sections.
3.3.1 Sender Module
Before a fully-functional receiver was developed using the FPGA board, the team
worked on the Sender Module first mainly because the process performed by the Receiver
Module are simply the reverse of those in the Server. To work on this component, the
team learned the fundamentals of voice sampling, encoding, and packetization. Figure 2.3
shows the flow chart that summarizes the Sender Module.
The Sender Module was implemented in Borland Delphi 7 using the WaveAudio
Package for Delphi 7.0 (Freeware Package Copyright by Kambiz R. Khojasteh)
Determine Local Address and Host
Name WAIT …
Started Recorder activated
Voice Sampling and
Recording to buffer Packetize data In the Buffer
UDP Server activated
Send Packets To receivers
Process Stopped?
Recorder and UDP Server Deactivated
no yes
Figure 2.3 Sender Module Flow Chart
8
specifically the LiveAudioRecorder. This component records audio from a specified
wave audio input device, and gives it to the application as data buffers. Using
LiveAudioRecorder, the audio format and its sampling rate can be specified including the
length of the buffer in which the audio signal will be stored. For the packetization of the
audio signals, User Datagram Protocol (UDP) was chosen considering the fact that audio
data is to be transmitted in real time. The UDPClient component of the Indy was used
since it supports UDP packet transmission. In addition, UDP supports broadcasting which
is the primary goal of this project. The PC Sender Module is coded in Delphi using the
Borland Delphi 7 compiler.
Figure 2.4 EPAS Sender Module
Figure 2.4 shows the dialog box of the Sender Module that displays the PC Name,
Local Address, Port, and the Destination Address. The Port and the Destination Address
are set to 3435 and 255.255.255.255 respectively since the application is broadcasting
9
[3]. The Start button activates both the recorder and the UDP server. Simultaneously the
recorder samples the input voice signals from the microphone and stores it in the buffer
while the UDP server opens the sockets necessary for UDP transmission. The recorder is
configured to sample Mono8 bit PCM at 48 KHz, while the size is predetermined to be
filled at 4 ms of recorded voice. The bandwidth of the Mono8bit48kHz format is 384
kbps, i.e.48000 sec samples x 8bits sample = 384kbps. The LiveAudioRecorder records
wave audio in user-defined buffers that include properties such as BufferCount and
BufferLength key. The BufferCount of the Sender Module was set to 5 while the total
duration or buffer length was set to 20 ms. About 4 ms of single data buffer of the
discrete audio signal is framed to packets for transmission. The moment a buffer is filled,
the data in the buffer is appended with the UDP Header, IP Header, Checksums,
Preamble, and Start of the Field Detector (SFD) according to IEEE 802.3 standards as
shown in Figures 2.5-6 below. The Sender Module then transmits the data packet to the
Ethernet Header
Header
Ethernet Data
Data
IP Header
Header
IP Data
Data
UDP
P
UDP Data
Data
PCM Header
Header
Audio Data
Data
Fig 2.5 Data Encapsulation
Encapsulation
Preamble (SFD)
(SFD) Destination MAC Address
Address Source MAC Address
Address Ethernet Type
Type IP Header
Header IP Protocol
Protocol IP checksum
checksum IP Source
Source IP Destination
Destination UDP Source Port
Port UDP Checksum
Checksum Ethernet Checksum
Checksum
UDP Payload
Payload
UDP Destination Port
Port UDP Payload Length
Length
Fig 2.6 Format of the Packet
Packet
Frames are
are
sent from top to bottom
bottom
Preamble/ SFD Destination MAC
Source MAC
Checksum Protocol Header Type
Destination port Source port Destination
Source
Payload Checksum
Payload length
Ethernet checksum
55555555555555D5 FF.FF.FF.FF.FF.FF
--
-- 11 --
08 00
3435 --
255.255.255.255 --
Assigned values
-- -- --
--
8 bytes 6 bytes 6 bytes
2 bytes 1 byte 9 bytes 2 bytes
2 bytes 2 bytes 4 bytes 4 bytes
No. of bytes
85 bytes 2 bytes 2 bytes
4 bytes
Fields
b0 b7 b1 b2 b3 b4 b5 b6
Octets within Frame
transmitted from top to
bottom
LSB MSB
Transmitted Left to Right
Figure 2.6 Format of the Packet
10
receiver. The source code of the Sender Module is shown in Appendix A.1.
As shown in the Protocol stack in Figure 2.5, the Ethernet packet encapsulates the
IP which in turn encapsulates the UDP. To start with, the preamble is composed of 7
bytes of 55h and D5h as the 8th byte which is the Start of Frame Delimiter for
synchronization and clock recovery [12]. The Destination MAC Address is 6 Bytes with
the hexadecimal value of FF.FF.FF.FF.FF.FF for the decimal-valued IP Address
255.255.255.255. On the other hand, the Source MAC Address is the 6-byte machine
address of the NIC of the PC server that is used as broadcaster. The value used for
Ethernet type is 08 00h since the only frames accepted are Internet Protocol (IP)
messages. The payload of the Ethernet packet, the IP packet, consists of a 9-byte IP
header and 1-byte IP protocol that has a value 11h since in this project the User Datagram
Protocol was used. The IP packet also includes an IP checksum of 2 bytes, 4 bytes each
for the IP Source and the IP Destination, 2 bytes each for the UDP Source and the
Destination Port, a 2-byte UDP Payload Length, and a 2-byte UDP Checksum. The UDP
payload is the audio data in PCM format. The audio data has a 55-byte header that
contains information such as the sampling rate, byte rate, audio format, bits per sample of
the PCM Voice data, followed by 192 bytes of voice data such that 48 kHz x 4ms = 192
bytes . Thus the payload is about 247 bytes. The packet is terminated with the 4-byte
Cyclic Redundancy Check (CRC) [12].
3.3.2 Receiver Module
RJ45
Figure 2.7a Block Diagram of Data flow in the Receiver
LAN83C185
FPGA LTC2624
DAC
11
The Receiver Module is developed using the Xilinx Spartan™ -3E Starter Board
and coded in VHDL using Xilinx ISE 8.2i included in the Starter Kit. Using this
software, the team developed a MAC controller and an audio player on the FPGA board.
The digital audio output of the FPGA audio player is converted to analog audio using the
onboard Linear Tech LTC2624 Quad DAC and used as input to an audio amplifier to
drive external audio speakers. Figure 2.7 shows the block diagram of the Receiver
Module with the I/O descriptions in Table 2.1.
SIGNAL DESCRIPTION
CLK_50MHz 50 MHz clock from the FPGA
RX_CLK Received clock from the MII
RX_DV Signal indicating that a valid data received in MII
RX_DATA 4 bit parallel data from the MII
SPI_MOSI Serial data to be inputted to the onboard DAC chip
SPI_SCK Clock used to latch data on the on board DAC chip
DAC_CLR Signal that clears the register of the DAC chip when set to low
DAC_CS Signal that enables data latching when set to low and DAC conversion
when set to high
Table 2.1 Receiver Module Signals
SFD AML BUFF DAC
CLK_50MHZ
RX_CLK
RX_DV
RX_DATA [0:3]
SPI_MOSI
SPI_SCK
DAC_CLR
DAC_CS
Figure 2.7b Block Diagram of FPGA Receiver Module
12
The data packet from the Sender Module is received by the Receiver Module
through the onboard RJ45 connector that is interfaced with the Standard MicroSystems
LAN83c185 10/100 Ethernet physical layer (PHY). This chip performs the necessary
conversions and processes done by the NIC of the PC server and outputs the information
needed to recover the voice data to the FPGA using the standard MII interface. This
information include the RX_CLK that gives the recovered clock rate from the received
packet, RX_DV which indicates validity of the signal received by the RJ45 connector,
and the RXD (the packet which is in 4 bits parallel). The receiver module was
programmed to ignore some parts of the received data packet and focus only on the
necessary information needed to recover the data as highlighted in Figure 2.8. This
module is subdivided into four parts as shown in Figure 2.9: SFD (Start of the Frame
Delimiter), AML (Address Matching Logic), Buffer, and the DAC (Digital to Analog
Converter).
Figure 2.8 Parts of the Data Packet
Ethernet preamble/SFD (synchronizer): 55 55 55 55 55 55 55 D5
Ethernet destination address (6 bytes)
Ethernet source address (6 bytes)
Ethernet type: 08 00 (=IP)
IP header(9 bytes)
IP protocol: 11 (=UDP)
IP checksum(2 bytes)
IP source (4 bytes)
IP destination (4 bytes)
UDP source port (2 bytes)
UDP destination port (2 bytes)
UDP payload length (2 bytes)
UDP checksum(2 bytes)
UDP payload (55 bytes PCM Header and 192 bytes of data
Ethernet checksum (4 bytes)
13
Data packets are received through the reception pins 3 and 6 of the RJ45
connector. Once received, PHY will check if the data is valid or not. If valid, RX_DV
will be set to high and this enables the Start of Frame Delimiter (SFD).
The SFD detects the start of the Ethernet Frame. Once the SFD is detected, the
AML checks if the packet information indicates that it is for the Receiver Module. If the
information matches, the Buffer saves the data within the packet. After the data is stored,
the DAC converts the digital data into analog to drive the external speakers.
Each component is discussed in detail in the succeeding sections.
SFD AML
Buffer DAC Amplifier And speaker
Data Valid? Detected?
Match? Terminate no
yes
no no
yes yes
Figure 2.9 Receiver Flow Chart
Wait for data
14
3.3.2.1 Start of Frame Delimiter
Signal Descriptions
RX_CLK (input) Received clock from the MII
RX_DV (input) Signal indicating that a valid data received in MII
RX_DATA (input) 4 bit parallel data from the MII
AML_Enable (output) Enables the AML module if set to high
Table 2.2 SFD Module Signals
The preamble of an Ethernet packet is composed of 7 bytes with a value 55H and
the 8th byte having a value of D5H. According to Ethernet Standard 802.3, the least
significant bit of a byte is sent first. Thus, 55H which is equivalent to 01010101b is bit-
reversed prior to transmission, i.e. sent as 10101010b while D5H (=11010101b) is sent as
10101011b. The PHY device, using the standard MII interface, outputs data to the FPGA
in nibbles so that there are 15 nibbles in this series “1010” and the 16th nibble is “1011”.
Figure 2.10 and Table 2.2 show the block diagram and corresponding descriptions
of the SFD module whose main function is to indicate if the end of the preamble is
reached. This means that the next nibble following the end of the preamble is the first
nibble indicating the MAC Address.
15
This function is achieved by setting a counter to count if there are already seven
bytes of the series 10101010 being received. The next byte should be the SFD which is
the series 10101011. Since the data from the PHY device associated with every clock
cycle of RX_CLK is in nibbles, the counter will count up to fifteen nibbles of “1010”.
Then it will check if the 16th nibble is “1011”. If the 16th nibble is “1011”, then the SFD
will enable the Address Matching Logic (AML) module. Otherwise it will wait for the
next data. Whether SFD is detected or not, the state of the SFD module will turn off after
processing. The VHDL code for the SFD module is written in appendix A.2. The
algorithm of SFD detector is shown in Figure 2.11 below.
Figure 2.11 SFD algorithm
Is Data valid?
Is received data “ 1010 ” ?
Is received data “ 1011 ” ?
Increment count
count<16?
Count=16?
Enable AML
Turn off state
Wait For next packet Set count=0
yes
No
yes
yes
yes
yes
No
No No
No
Received “ others ”
16
Fig 2.12 AML Block Diagram
MAC ETYPE PROTOCOL PORT IP
RX_CLK
AML Enable
RX_DATA [0:3]
BUFF Enable
3.3.2.2 Address Matching Logic (AML)
The AML unit examines the received packet to check whether it is sent by the
Sender Module for the Receiver Module or just another packet from other sources. This is
done by assigning fixed information for the FPGA receiver, declared as constant, to be
used by the AML for reference. If the information in the received packet matches that of
the fixed information, then the AML enables the Buffer.
As shown in Figure 2.12, the AML Module is subdivided into five components:
MAC, ETYPE, PROTOCOL, IP and PORT. The MAC component is responsible for
checking if the Destination MAC address of the received packet is the same with the
MAC Address assigned to the receiver module. If they match, the MAC component
enables ETYPE whose function is to check if the Ethernet type used in the received
packet is Internet Protocol (IP). Again, a match is found, the next component is enabled.
This process continues until all the components in the AML module detect a match.
Table 2.3 lists the descriptions and definitions of the input and output elements within the
AML block. Figure 2.13 summarizes the algorithm for the AML Module.
SIGNAL DESCRIPTIONS
RX_CLK (input) Received Clock from MII
AML_ENABLE (input) Enables the AML module
RX_DATA (input) 4 bit parallel data from the MII
BUFF_ENABLE (output) Enables the buffer module
Table 2.3 AML Module Signals
17
Not all of the bits received after the SFD contains necessary information to
determine whether or not the received packet is for the FPGA Receiver. Thus, there are
instances when this component will skip some bits. Only the bits pertaining to relevant
information is saved.
The MAC component checks if the destination MAC Address is that assigned for
broadcasting which is FF.FF.FF.FF.FF.FF. Since the bits that refer to the MAC
destination address follows immediately after the SFD as shown in refer to Figure 2.8, the
MAC Component will save the received nibbles right after the AML is enabled. A total
of 12 nibbles are saved and compared with the fixed MAC Address. If they match,
ETYPE Component will be enabled.
The ETYPE Component checks if the Ethernet Type of the received packet
corresponds to 08 00h (for IP). This subunit similarly saves the received Ethernet type
and compares it with the expected Ethernet type. However, this subunit must first skip a
count of about 12 cycles that is equivalent to 12 nibbles (Source MAC Address) of data
before starting to store the Ethernet type.
AML enable?
Match?
Check MAC
Check
Ethernet
type
Check IP Check PortCheck
protocol
Match?Match? Match?Match?
Enable buffer
yes
No
yes
yesyes
yes
yes
Fig 2.13 AML Flow Diagram
18
The PRO component focuses on the IP Protocol used. This component does the
same mechanism as the previous component but it skips the 18 nibbles referring to the 9-
byte IP header (refer to Figure 2.8) before storing the IP Protocol of the data received and
comparing it with the expected IP Protocol, in this instance, UDP.
Figure 2.14 Address Matching Logic component Process
The IP Component stores the received Destination IP Address after skipping 4
nibbles of the received data and compares it with the IP address for broadcasting which is
255.255.255.255. If it is a match, the next component will be enabled. The final
component checks if the Destination Port of the received packet is the same with the
assigned Destination port (3435). If they match, the Buffer unit will be enabled. Whether
a match is detected or not, the state of each AML subunit will return to „0‟ after
completing the process as shown in Figure 2.14.
Need to skip? Count by Nibbles
Save then compare
Match? Enable next stage
terminate
Wait for stage enable Reset count
yes
yes
No
No
19
252
Block 1 Block 16 …
0 1
…
253 254 255
4 4 …
4 4 … 4 4 … 4 8 … 4 8 … 4 4 … 4 4 … 4 4 … 4 4 …
B7 B6 B5 B3 B4 B0 B1 B2
bits
… …
4 4 4 4 4 4 4 8 4 8 4 4 4 4 4 4 4 4
bits
… …
3.3.2.3 Buffer (BUFF)
The Buffer Module, once enabled, will skip 117 nibbles of the received data
which corresponds to the 2-byte payload size, 2-byte UDP checksum, and 55-byte PCM
header as shown in Figure 2.8. The BUFF Module then stores the next bits to the block
RAM. There are 16 block RAM‟s that are 8 bits wide and 256 bytes deep as illustrated in
Figure 2.15.
Figure 2.15 RAM : [8:256]x16
The BUFF component receives 4 bits per rising edge of the RX_CLK. Since the
block ram can only be written with 8-bit data, a holder array which is 8 bit wide and 4
bytes deep is provided to temporarily store the nibbles received and pair the nibbles to
construct a byte. As soon as a byte is formed or after 2 clock cycles of the RX_CLK, the
byte is saved to the ram on every rising edge of another clock which is half the rate of
RX_CLK. The formation of the bytes within the HOLDER array and the saving of such
bytes to the RAM work in parallel simultaneously. This process continues while a byte
counter is incremented. When the byte counter reaches the limit, the saving of the coming
nibbles is stopped and the state of the buffer is turned off while the next module (DAC) is
enabled or informed that a set of data has been saved on the ram. The formula for the
limit of byte to be saved is:
20
BYTE_LIMIT :=(( SAMPLING_RATE/1000)*(SAMPLE_LENGTH/BUFF_NUM));
Where: BYTE_LIMIT = Number of bytes to be saved
SAMPLING_RATE = Sampling rate used at the sender
SAMPLE_LENGTH = Length of the sampling at the sender (20 ms)
BUFF_NUM = Number of buffers used at the sender (5)
There are two clocks used in saving data from the holder array to the block ram.
One is to adjust the address and another to latch the data to one of the slots in the block
ram. The program secures that the address is adjusted before the data is latch to give
enough time to jump from one block ram to another if the current block being written is
already full. The saving starts from block 1 at address “00000000” up to “11111111”
which would indicate that the current block is already full.
By the time the first block is full; a pointer then points to the next block and fills it
with the next voice data received. When this 2nd block is full, the pointer points to the
third then to the fourth, to the fifth ... up to the last (the sixteenth), and then back to the
first array overwriting the present data. The cycle goes on. Figure 2.16 shows the process
flow for the BUFFER module.
21
Count=limit?
Save a byte to ram And increment counter
Buffer enabled?
Skip 96 nibbles
Save nibbles to holder and form a byte
Turn the BUFF Module off and enable DAC
Wait for request from DAC
Adjust address
Wait
Adjust address include pointer if block is full
yes
No
yes
No
Read ram and output data
include pointer if block is full
Figure 2.16 Buffer process flow
3.3.2.3 Digital to Analog Conversion (DAC)
SPI_MOSI
SPI_SCK
DAC_CLR
SPI_MISO
DAC_CSAnalog
Signal
Figure 2.17 Interconnection between the FPGA and the DAC [14 & 15]
The team uses the onboard DAC to convert the stored data in the buffer into
analog signals. Figure 2.17 shows how the FPGA is connected to the DAC.
22
Figure 2.18 DAC clock relationships [14 & 15]
The DAC chip begins saving the data in its internal register after DAC_CS turns
“0”. A total of 32 bits of data is latched to the register (32-bit mode) of the DAC Chip bit-
by-bit for every rising edge of the SPI_SCK. This 32-bit serial data is latched in the
following manner. The first 8 bits are considered “don’t care” values; followed by the 4-
bit command that indicates the function to be performed by the DAC. In the project, the
4-bit command is “0011” which corresponds to the action of immediately updating the
register and its output by the data input. Following the command is the Address. There
are 4 possible addresses that indicate the output pin of the analog signal produced. The
address “1111” which enables all of the output pins is used in this project.
Fig 2.19 DAC input data [14 & 15]
23
The 12-bit unsigned data comes after the Address. Since the data saved in the
buffer is in 8-bit PCM mono format which is unsigned, it should undergo a digital signal
processing (DSP). The team had tried three methods in producing a 12 bit data. The first
one is affixing 4 zeros at the most significant bit leaving the value of the data as it is. The
second is affixing the four zeros at the least significant bit which raised the step of each
sample by a factor of 16. This is actually expanding the signal linearly. The third method
which the team currently adopts is Expanding part of the Digital Companding. The team
had arrived to this solution after reading materials about audio processing. It is assumed
that the PC sender compressed the audio signal before sampling.
In companding, the signal is expanded nonlinearly. The signal is divided into 7
segments. The first segment corresponds to low digital value while those belonging to
segment 7 are those with highest values. The degree of expansion increases as with the
segment number. Those at segment 1 are not expanded while those at segment are
“stretched” to the maximum levels. The detailed observations and reasons why the team
decided to use companding is discussed in the tests and results (section 2.5, page30).
After the DSP, the 12 bit data is appended with the other necessary data and are
latched to the internal register of the DAC chip. Then the DAC_CS signal is set to high
enabling the DAC chip to convert the 12- bit data in its register to analog.
The rate of the conversion of each byte to analog voltage should be the same as
the sampling rate of the sender module. To achieve this, the team derived some clocks
from the on board 50 MHz clock with the following calculations:
For the DAC_CS:
1 period of DAC_CS = (50MHz / sampling rate) rising edge of the 50MHz clock
= PERIOD_CS
24
This result was split into two for the instant when the DAC_CS is high and when
DAC_CS is low. The team decided that if the period is not exactly divisible by two, the
remainder should be appended to the instant when DAC_CS is high.
HIGH_CS = ((PERIOD_CS/2)+(PERIOD_CS mod 2));
DOWN_CS = ((PERIOD_CS/2));
For the other clocks, since we need 32 bits of data to be latched to the DAC chip
during the DAC_CS signal is low, we divided the DOWN_CS rising edges by 32 parts,
i.e.
PERIOD_SCK = ((DOWN_CS)/32);
This indicates 1 period of DATA_CLK and SPI_SCK clocks. The DATA_CLK is
used to output the 32-bit data serially from the DAC module. On the other hand the
SPI_SCK clock is to be used by the DAC chip to latch the incoming serial data to its
internal register. To ensure that the data to be latched is already stable the DATA_CLK
and SPI_SCK clocks should be of the same period and out of phase with each other by
about a quarter of the SPI_SCK period (DATA_CLK is advanced). So the PERIOD_SCK
is divided into 4 segments and each quarter is allotted to the time when DATA_CLK or
SPI_SCK is high or low.
UP_DATA_CLK = (PERIOD_SCK/4);
-- counts before data_clk signal is set to high
U_D_C = (PERIOD_SCK/4);
UP_SCK = (U_D_C + (PERIOD_SCK/4));
-- counts before SPI_SCK signal is set to high
U_S = (U_D_C + (PERIOD_SCK/4));
DOWN_DATA_CLK = (U_S + (PERIOD_SCK/4));
-- counts before data_clk signal is set to low
D_D_C = (U_S + (PERIOD_SCK/4));
DOWN_SCK = (D_D_C + (PERIOD_SCK/4));
-- counts before SPI_SCK signal is set to low
25
The remainders on the dividing the DOWN_CS by 32 and dividing the
PERIOD_SCK by 4 are summed up to be allotted as allowance for the moment when
data request and preconditioning (DSP) is done, ie:
LOW_CS_EXTRA = ((H_C mod 32)+(PERIOD_SCK mod 4));
-- Counts after DAC_CS signal is set to low
The algorithm for clock derivation is shown below (sampling rate is 11.025kHz):
Figure 2.20 DAC Clock derivation algorithm
This process means the counter should have this count for each event: 28 rising edges
after the DAC_CS is set to low, the counter shall be reset to 1; at count = 19, data_clk
goes high; at count = 36, SPI_SCK goes high; at count = 53, data_clk does down; and at
count = 70, SPI_SCK goes down and the counter is reset to 1. This cycle is repeated for
26
32 times after which the DAC_CS is set to High and the other clocks are set to zero. This
process is described in Figure 2.19.
Once a set of bytes (determined by byte_limit) is stored in the buffer, the buffer
will enable the DAC module. When the DAC module is informed by the BUFF module
that a set of bytes was written in the ram the DAC module increments a counter. The
DAC module then requests 1 byte of data from the buffer. The byte fetched will be
processed (DSP) Bit to make it a 12 bit data which is suitable for the on board DAC of
the FPGA. After the DSP, 8 bits of don‟t care, 4 bits of command, 4 bits of output
address shall be appended at the MSB while 4 don‟t care bits shall be put after the least
significant bit. The resulting 32 bit data shall be fed to the SPI_MOSI input of the on
board DAC in a serial manner, MSB first. After the 32 bits are latched by the on board
DAC, the conversion of the digital data to analog will start. The analog output of the
DAC shall be fed to the amplifier and speaker set up. This process shall continue until a
set of bytes is converted to analog as monitored by the BYTE_LIMIT. At that point the
counter shall be decremented. This process shall continue until all the data stored is
converted to analog signals which is indicated when the counter reaches zero. When the
counter reaches zero the DAC module is turned off. Figure 2.20 summarizes the
algorithm for the DAC.
27
Wait for
enable
Increment
count
Turn
State on
Request a byte
from BUFF
Receive data
from BUFF
Digital signal
processing
Append
necessary bits
Output data to
DAC chip
Increment
count_byte
Count_byte =byte_limit?
No
yes
Count = 0?
No
yes
Reset count_byte
& decrement
count
Turn DAC
module off
Digital to analog
conversion
Drive the
speaker
Wait for
enable
Wait for
enable
Increment
count
Increment
count
Turn
State on
Turn
State on
Request a byte
from BUFF
Request a byte
from BUFF
Receive data
from BUFF
Receive data
from BUFF
Digital signal
processing
Digital signal
processing
Append
necessary bits
Append
necessary bits
Output data to
DAC chip
Output data to
DAC chip
Increment
count_byte
Increment
count_byte
Count_byte =byte_limit?
No
yes
Count = 0?
No
yes
Reset count_byte
& decrement
count
Turn DAC
module off
Count_byte =byte_limit?
No
yes
Count = 0?
No
yes
Reset count_byte
& decrement
count
Turn DAC
module off
Count_byte =byte_limit?
No
yes
Count_byte =byte_limit?
Count_byte =byte_limit?
No
yes
Count = 0?
No
yes
Count = 0?Count = 0?
No
yes
Reset count_byte
& decrement
count
Reset count_byte
& decrement
count
Turn DAC
module off
Turn DAC
module off
Digital to analog
conversion
Digital to analog
conversion
Drive the
speaker
Drive the
speaker
Figure 2.21 Digital to Analog Converter Summary
28
3.4 Procedure for Setting-up the System
Figure 2.22 EPAS System Set Up
The PC Server, Ethernet switch and FPGA are all connected by the twisted pair
Category 5 cable while the microphone, amplifiers and speakers are hardwired. The
Ethernet switch looks for the receiver and transmits the packets sent by the broadcaster.
The user initializes the Sender Module (broadcaster) on the PC server. When the Receiver
Module is switched on, the user can begin transmission by clicking the Start button on the
Sender Module dialog box and speaking through the microphone. The voice data is then
transmitted to the Receiver Module and heard through the audio speakers in real time.
Hub/ Router
Server
LAN
29
3.5 Tests and Results
Tests were conducted to determine the functionality of each component of the
EPAS system. All components of the Receiver Module were simulated first before being
implemented and tested on the FPGA.
The first test was done on the SFD detector of the Receiver Module. After the
SFD code was loaded to the FPGA board, the FPGA was connected to the Local Area
Network and loaded Ethernet packets from different computers in the LAN. The RX_DV
signal from the PHY which indicates that a valid data is received was used to light an
indicator LED on the FPGA board, i.e. if an SFD is detected, the LED should light up.
The output of the SFD Detector which enables the AML unit was also connected to
another indicator LED on the FPGA board. The main objective was to determine if the
SFD detector developed by the group could detect the SFD of Ethernet packets from
other computers. The team observed that the two LEDs continuously blinked indicating a
successful result.
The second test was done to determine the functionality of the broadcaster. To
accomplish this, the team also programmed a Receiver Module application on the PC.
The Sender Module/broadcaster was run on one PC and the Receiver Module on another
PC, both of which are connected to the same LAN. If the Receiver Module application
could successfully broadcast the data sent through the broadcaster, it means that the
Sender Module could properly transmit audio data. Several attempts were made before a
successful PC-to-PC voice transmission was achieved. The voice quality was choppy and
there were echoes heard at the receiver. Moreover there was a delay in the transmission
of audio data. However, the test was considered a success for it accomplished the primary
objective of transmitting an audio signal from PC-to-PC. The team tried to improve the
quality of the speech being transmitted by the broadcaster. Finally the team has
developed the Sender Module whose voice quality was no longer choppy, no echoes and
no delay. We test it the improved Sender module by using loop back mechanism.
The next test was done to establish connection between the PC server and the
FPGA receiver, i.e. to determine if the FPGA can detect the SFD of the packets sent by
the Sender Module. Again, LEDs on the FPGA were used to indicate that the test was
successful.
30
Another test was performed to determine the functionality of the AML unit by
assigning 8 LEDs, the aim was to turn on the LEDs whenever the following are enabled,
i.e. a match is made: RX_DV, SFD, MAC Address, Ethernet type, Protocol, IP Address
and Port. When there is a match, another LED was used to indicate whether the Buffer
was enabled. The FPGA board was then connected to the LAN thru the Ethernet switch.
The Sender Module in the PC was then started and the FPGA was able to detect the
packets sent by the PC server as indicated by the assigned indicator LEDs lighting up.
The next test that the team did was to determine the functionality of the Buffer
component. Eight (8) LEDs were used to determine if data was stored in the buffer and
four (4) switches were used to provide the incoming data. Again, successful results were
indicated by all the LEDs lighting up.
The DAC component was also tested for functionality. The team stored 8-bit data in the
Buffer ranging from 0 to 255 then from 255 to 0, corresponding to 8-bit PCM. The FPGA
should extract the data and append the necessary bits to form a 32-bit data. It shall then
be fed to the onboard DAC. The output of the DAC was viewed on a digital oscilloscope.
The test was successful in displaying a triangular wave that was composed of step
voltages (Pulse Amplitude Modulation Signals).
A final test was done to determine the functionality of the whole system. The PC
server was connected to the LAN and the FPGA board was configured using the VHDL
developed codes and connected to the LAN. The Sender Module in the PC was then
started and a public announcement was made. The output of the DAC chip was connected
to an audio speaker and an oscilloscope.
The team tried three methods in processing the audio data. The first was
appending three zeros in the most significant bit of the 8-bit data leaving the received
value untouched. With this was method the output at the speaker was not intelligible, and
the oscilloscope displayed a very flat wave form of only peaks and zeros.
The team tried to stretch the signal that the intermediate voltage levels will be
produced. This is done by multiplying a constant of 16 to all data received (four zeros are
appended on the least significant bit of the received data). With this method, the sound
quality was improved. It was intelligible; however the speaker‟s voice is robotic.
31
The third test was tried to eliminate the robotic quality of the sound. The team
again expanded the signal; however it was no longer done linearly. The high level signals
are amplified more than the low level signals. This method is based upon the Digital
Companding which is used in noise reductions in most audio systems. With this method,
the result was satisfactory. The voice was very intelligible and the robotic quality was
eliminated. However, there was still a helicopter sound on the background. The team
suspects that such noise is due to aliases. Thus, at present, the team is searching for the
methods in digital filtering.
Nevertheless, the primary objective of the team which was to transmit audio
signals from PC to the FPGA Receiver was achieved. Thus, all-in-all the team considers
this project a success.
32
Chapter 4
Summary of Results, Conclusions and Recommendations
The purpose of this project was to design and build an Ethernet-based Public
Addressing System using a personal computer as a server/broadcaster and a Xilinx
Spartan™-3E Development Board as the receiver. For this purpose, the team aimed to
transmit audio signals from the PC over the LAN to the FPGA receiver and reproduce the
signals using external audio speakers connected to the board. Based on the tests done on
the system, voice announcements can be successfully transmitted using the FPGA board
as a receiver.
However, the quality of the voice heard over the audio speakers still needs
improvement. The team is still working on ways to improve the quality of the speech
output over the following days. Furthermore, Real-time Transport Protocol can also be
implemented to further increase the quality of the sound by decreasing packet reception
errors due to traffic.
On the other hand, the team has demonstrated the capability of utilizing any
existing Local Area Network to implement a Public Addressing System using a PC on
one end and an FPGA board on the receiving, which was the primary objective of this
design. Thus, the team considers the whole system as a successful achievement.
For further development of this project, audio compressions and other signal
processing techniques should be employed to improve the quality of the reproduced
sound. Multicasting instead of broadcasting can also be implemented by developing a
Sender Module in the FPGA receiver that would manage the Internet Group Management
Protocol (IGMP). This would increase the efficiency and security of the system with
regards to the Bandwidth. The team has already developed a Multicaster on the PC server
but was not able to test it properly. However, the team intends to pursue the development
of the system to do multicasting instead of broadcasting.
Other developments can be done to this design such as performing audio
multicasting using the FPGA as the Sender and a Receiver. Doing such, voice over IP
technology shall be implemented. Using FPGA, microphones, and speakers on both ends
of the system, modern digital telephony can be demonstrated. Indeed, FPGAs are very
33
powerful tools for developing and implementing communications projects. In doing this
project, the team gained a lot of knowledge on programming using VHDL, implementing
data communications and digital electronics concepts as well learning troubleshooting
skills.
Device utilization summary:
Selected Device : 3s500efg320-5
Number of Slices: 544 out of 4656 11%
Number of Slice Flip Flops: 488 out of 9312 5%
Number of 4 input LUTs: 945 out of 9312 10%
Number of IOs: 13
Number of bonded IOBs: 13 out of 232 5%
IOB Flip Flops: 4
Number of BRAMs: 16 out of 20 80%
Number of GCLKs: 4 out of 24 16%
34
References
[1] Steinke S, Network Tutorial (Fifth Edition), CMP Books, 2003
[2] Ashenden P, The VHDL Cookbook (First Edition), 1990
[3] Mogul J, RFC 919: Broadcasting Internet Datagrams, Stanford University,
October 1984
[4] Postel J, RFC 768: User Datagram Protocol, ISI, August 1980
[5] UDP Specifications
http://www.javvin.com/protocol/rfc768.pdf (Last accessed 7/7/2007)
[6] The WAVE Format
http://www.lightlink/tjweber/StripWav/Wave.html#WAVE
(Last accessed 9/21/2007)
[7] Internet Protocol (IP) Multicast
http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/ipmulti.htm
(Last accessed 9/21/2007)
[8] Ethernet Codes: Multicast (including Broadcast) Addresses
http://www.cavebear.com/archive/cavebear/Ethernet/Ethernet.txt
(Last accessed 9/23/2007)
[9] 10BASE-T FPGA interface part 0 - A recipe to send Ethernet traffic
http://www.fpga4fun.com/10BASE-T0.html (Last accessed 7/7/2007)
[10] 10BASE-T FPGA interface part 1 – How Ethernet works
http://www.fpga4fun.com/10BASE-T1.html (Last accessed 7/7/2007)
[11] 10BASE-T FPGA interface part 2 - IP/UDP over Ethernet
http://www.fpga4fun.com/10BASE-T2.html (Last accessed 7/7/2007)
[12] 10BASE-T FPGA interface part 3 – Sending Packets
http://www.fpga4fun.com/10BASE-T3.html (Last accessed 7/7/2007)
[13] 10BASE-T FPGA interface part 4 – Receiving Packets
http://www.fpga4fun.com/10BASE-T4.html (Last accessed 7/7/2007)
[14] Linear Technology Corporation, LTC2604/LTC2614/LTC2624-Quad 16-Bit Rail-
to-Rail DACs in 16-Leads SSOP
35
[15] Xilinx, Spartan-3E Starter Kit Board User Guide, UG230 (v1.0), March 2007
[16] SMSC, LAN83C185 High Performance Single Chip Low Power 10/100 Ethernet
Physical Layer Transceiver (PHY) Datasheet
[17] LAN/MAN Standards Committee of the IEEE Computer Society, IEEE Std
802.3-2005, Section One
[18] Essential Delphi
http://www.marcocantu.com/edelphi (Last accessed 9/23/2007)
[19] Perkins C, RTP Audio and Video for the Internet, Addison Wesley,2003
[20] UDP: User Datagram Protocol
http://www.javvin.com/protocolUDP(Last accessed 9/23/2007)
[21] Buttery A, Ethernet Based Public Address System, 2003
[22] PCM: Pulse Code Modulation
http://www.wikipedia.com(Last accessed 3/21/2008)
[23] Marohombsalic A. and etc, Ethernet Based Public Addressing System, 2007
[24] FPGA info1
http://www.fpga4fun.com (Last accessed 7/7/2007)
[25] Tomasi W, Advanced Electronic Communications Systems, 2004
36
Appendix A: HDL DESCRIPTIONS
A.1: EPAS TOP MODULE
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 01:33:13 01/01/2004
-- Design Name:
-- Module Name: EPAS_top - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity EPAS_TOP is
port( RX_CLK,
CLK_50MHZ,
RX_DV : in std_logic;
RX_DATA : in std_logic_vector(0 to 3);
SPI_MOSI,
SPI_SCK,
DAC_CLR,
LED_BUFF,
LED_DAC,
DAC_CS : out std_logic);
end EPAS_TOP;
architecture Behavioral of EPAS_top is
component SFD_DETECTOR is
port ( RX_CLK, -- input from RX_CLK of MII in FPGA;
RX_DV : in STD_LOGIC; -- input from RX_DV of MII in FPGA;
RX_DATA : in STD_LOGIC_VECTOR(0 TO 3); -- input from RXD of MII in FPGA;
AML_EN : out STD_LOGIC); -- output to LD0 of FPGA
end component;
component AML is
port(RX_CLK,
AML_EN : in std_logic;
RX_DATA : in std_logic_vector(0 to 3);
BUFF_EN : out std_logic
);
end component;
component BUFF is
port(RX_CLK,
REQUEST,
CLK_50MHZ,
DAC_ON,
37
BUFF_EN : in STD_LOGIC;
RX_DATA : in STD_LOGIC_VECTOR(0 TO 3);
LED_BUFF,
DAC_EN : out STD_LOGIC;
DATA_OUT : out STD_LOGIC_VECTOR(7 downto 0)
);
end component;
component DAC is
port( DAC_EN,
CLK_50MHZ : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
SPI_MOSI,
SPI_SCK,
DAC_CLR,
REQUEST,
LED_DAC,
DAC_ON,
DAC_CS : out std_logic
);
end component;
signal SFD_TO_AML,AML_TO_BUFF,BUFF_TO_DAC,ASK_DATA,WIRE_DAC_ON: std_logic;
signal DATA_BUS: std_logic_vector(7 downto 0);
begin
SFD: SFD_DETECTOR
port map(RX_CLK => RX_CLK,
RX_DV => RX_DV,
RX_DATA => RX_DATA,
AML_EN => SFD_TO_AML
);
MATCH : AML
port map(RX_CLK => RX_CLK,
AML_EN => SFD_TO_AML,
RX_DATA=> RX_DATA,
BUFF_EN=> AML_TO_BUFF
);
STORE: BUFF
port map(RX_CLK => RX_CLK,
REQUEST => ASK_DATA,
BUFF_EN => AML_TO_BUFF,
RX_DATA => RX_DATA,
CLK_50MHZ => CLK_50MHZ,
DAC_EN => BUFF_TO_DAC,
LED_BUFF => LED_BUFF,
DAC_ON => WIRE_DAC_ON,
DATA_OUT => DATA_BUS
);
CONVERT : DAC
port map(DAC_EN => BUFF_TO_DAC,
CLK_50MHZ => CLK_50MHZ,
DATA_IN => DATA_BUS,
SPI_MOSI => SPI_MOSI,
SPI_SCK => SPI_SCK,
DAC_CLR => DAC_CLR,
REQUEST => ASK_DATA,
LED_DAC => LED_DAC,
DAC_ON => WIRE_DAC_ON,
DAC_CS => DAC_CS
);
end Behavioral;
38
A.2:SFD DETECTOR
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:45:15 10/03/2007
-- Design Name:
-- Module Name: SFD_DETECTOR - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SFD_DETECTOR is
port ( RX_CLK, -- input from RX_CLK of MII in FPGA;
RX_DV : in STD_LOGIC; -- input from RX_DV of MII in FPGA;
RX_DATA: in STD_LOGIC_VECTOR(0 TO 3); -- input from RXD of MII in FPGA;
AML_EN: out STD_LOGIC -- output to enable the AML module
);
end SFD_DETECTOR;
architecture Behavioral of SFD_DETECTOR is
signal STATE_SFD : std_logic := '0';
signal RESET_SFD : std_logic := '0';
signal ENABLE : std_logic := '0';
signal COUNT_SFD : integer := 0;
begin
AML_EN <= ENABLE;-- connects internal signal enable to output port LED_EN
process(RX_DV,RESET_SFD)
begin
if rising_edge(RX_DV) then
STATE_SFD <= '1';
end if;
if RESET_SFD = '1' then
STATE_SFD <= '0';
end if;
end process;
process(RX_CLK,STATE_SFD,COUNT_SFD)
begin
if rising_edge(RX_CLK) then
if STATE_SFD = '1' then
if RX_DATA = "1010" then
COUNT_SFD <= COUNT_SFD + 1;
elsif RX_DATA = "1011" then
if COUNT_SFD = 15 then
ENABLE <= '1';
39
RESET_SFD <= '1';
end if;
COUNT_SFD <= 0;
else
COUNT_SFD <= 0;
end if;
else
ENABLE <='0';
RESET_SFD <= '0';
end if;
end if;
end process;
end Behavioral;
40
A.3 ADDRESS MATCHING LOGIC
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 10:38:09 10/29/2007
-- Design Name:
-- Module Name: AML - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity AML is
port(RX_CLK,
AML_EN : in std_logic;
RX_DATA : in std_logic_vector(0 to 3);
BUFF_EN : out std_logic
);
end AML;
architecture Behavioral of AML is
signal STATE_MAC : std_logic := '0';
signal STATE_ETYPE : std_logic := '0';
signal STATE_PRO : std_logic := '0';
signal STATE_IP : std_logic := '0';
signal STATE_PORT : std_logic := '0';
signal RESET_MAC : std_logic := '0';
signal RESET_ETYPE : std_logic := '0';
signal RESET_PRO : std_logic := '0';
signal RESET_IP : std_logic := '0';
signal RESET_PORT : std_logic := '0';
signal MATCH_MAC : std_logic := '0';
signal MATCH_ETYPE : std_logic := '0';
signal MATCH_PRO : std_logic := '0';
signal MATCH_IP : std_logic := '0';
signal MATCH_PORT : std_logic := '0';
constant FIX_MAC : std_logic_vector(0 to 47):= "111111111111111111111111111111111111111111111111"; --
broadcast MacAddress(ff.ff.ff.ff.ff.ff)
constant FIX_ETYPE : std_logic_vector(0 to 15):= "0001000000000000";-- 08 00(IP)
constant FIX_PRO : std_logic_vector(0 to 7) := "10001000";-- 11(UDP)
constant FIX_IP : std_logic_vector(0 to 31):= "11111111111111111111111111111111";-- broadcast
(255.255.255.255)
constant FIX_PORT : std_logic_vector(0 to 15):= "1011000011010110";-- 0D 6B(3435)
signal RX_MAC : std_logic_vector(0 to 47):= (others => '0');
signal RX_ETYPE : std_logic_vector(0 to 15):= (others => '0');
signal RX_PRO : std_logic_vector(0 to 7):= (others => '0');
signal RX_IP : std_logic_vector(0 to 31):= (others => '0');
signal RX_PORT : std_logic_vector(0 to 15):= (others => '0');
signal RECOUNT_ETYPE: std_logic := '0';
signal RECOUNT_PRO : std_logic := '0';
41
signal RECOUNT_IP : std_logic := '0';
signal RECOUNT_PORT : std_logic := '0';
signal COUNT_MAC : integer := 1;
signal COUNT_ETYPE : integer := 1;
signal COUNT_PRO : integer := 1;
signal COUNT_IP : integer := 1;
signal COUNT_PORT : integer := 1;
begin
BUFF_EN <= MATCH_PORT;
--CHECK IF THE DESTINATION MACHINE ADDRESS OF THE RECEIVED PACKET
--BELONGS TO THE FPGA RECEIVER
MAC_ON:process(AML_EN,RESET_MAC)
begin
if rising_edge(AML_EN)then
STATE_MAC <= '1';
end if;
if RESET_MAC = '1' then
STATE_MAC <= '0';
end if;
end process;
MAC : process(RX_CLK,STATE_MAC,COUNT_MAC,RX_MAC)
begin
if rising_edge(RX_CLK)then
if STATE_MAC = '1' then
if COUNT_MAC = 13 then
if RX_MAC = FIX_MAC then
MATCH_MAC <= '1';
end if;
RESET_MAC <= '1';
COUNT_MAC <= 1;
else
RX_MAC((COUNT_MAC*4)-4) <= RX_DATA(0);
RX_MAC((COUNT_MAC*4)-3) <= RX_DATA(1);
RX_MAC((COUNT_MAC*4)-2) <= RX_DATA(2);
RX_MAC((COUNT_MAC*4)-1) <= RX_DATA(3);
COUNT_MAC <= COUNT_MAC + 1;
end if;
else
MATCH_MAC <= '0';
RESET_MAC <= '0';
RX_MAC <= (others => '0');
end if;
end if;
end process;
--CHECK IF THE ETHERNET TYPE USED IN THE RECEIVED PACKET
--BELONGS TO THE FPGA RECEIVER (IP)
ETYPE_ON:process(MATCH_MAC,RESET_ETYPE)
begin
if rising_edge(MATCH_MAC)then
STATE_ETYPE <= '1';
end if;
if RESET_ETYPE = '1' then
STATE_ETYPE <= '0';
end if;
end process;
ETYPE : process(RX_CLK,STATE_ETYPE,COUNT_ETYPE,RECOUNT_ETYPE,RX_ETYPE)
begin
if rising_edge(RX_CLK)then
if STATE_ETYPE ='1' then
if RECOUNT_ETYPE = '0' then
if COUNT_ETYPE < 11 then
COUNT_ETYPE <= COUNT_ETYPE+1;
else
RECOUNT_ETYPE <= '1';
COUNT_ETYPE <= 1;
end if;
else
if COUNT_ETYPE = 5 then
42
if RX_ETYPE = FIX_ETYPE then
MATCH_ETYPE <= '1';
end if;
RESET_ETYPE <= '1';
COUNT_ETYPE <= 1;
RECOUNT_ETYPE <= '0';
else
RX_ETYPE((COUNT_ETYPE*4)-4) <= RX_DATA(0);
RX_ETYPE((COUNT_ETYPE*4)-3) <= RX_DATA(1);
RX_ETYPE((COUNT_ETYPE*4)-2) <= RX_DATA(2);
RX_ETYPE((COUNT_ETYPE*4)-1) <= RX_DATA(3);
COUNT_ETYPE <= COUNT_ETYPE + 1;
end if;
end if;
else
MATCH_ETYPE <= '0';
RESET_ETYPE <= '0';
RX_ETYPE <= (others => '0');
end if;
end if;
end process;
--CHECK IF THE IP PROTOCOL USED IN THE RECEIVED PACKET
--BELONGS TO THE FPGA RECEIVER (UDP)
PRO_ON:process(MATCH_ETYPE,RESET_PRO)
begin
if rising_edge(MATCH_ETYPE)then
STATE_PRO <= '1';
end if;
if RESET_PRO = '1' then
STATE_PRO <= '0';
end if;
end process;
PROTOCOL : process(RX_CLK,STATE_PRO,COUNT_PRO,RECOUNT_PRO,RX_PRO)
begin
if rising_edge(RX_CLK)then
if STATE_PRO ='1' then
if RECOUNT_PRO = '0' then
if COUNT_PRO < 17 then
COUNT_PRO <= COUNT_PRO+1;
else
RECOUNT_PRO <= '1';
COUNT_PRO <= 1;
end if;
else
if COUNT_PRO = 3 then
if RX_PRO = FIX_PRO then
MATCH_PRO <= '1';
end if;
RESET_PRO <= '1';
COUNT_PRO <= 1;
RECOUNT_PRO <= '0';
else
RX_PRO((COUNT_PRO*4)-4) <= RX_DATA(0);
RX_PRO((COUNT_PRO*4)-3) <= RX_DATA(1);
RX_PRO((COUNT_PRO*4)-2) <= RX_DATA(2);
RX_PRO((COUNT_PRO*4)-1) <= RX_DATA(3);
COUNT_PRO <= COUNT_PRO + 1;
end if;
end if;
else
MATCH_PRO <= '0';
RESET_PRO <= '0';
RX_PRO <= (others => '0');
end if;
end if;
end process;
--CHECK IF THE DESTINATION IP ADDRESS USED IN THE RECEIVED PACKET
--BELONGS TO THE FPGA RECEIVER (255.255.255.255 "BROADCAST")
43
IP_ON:process(MATCH_PRO,RESET_IP)
begin
if rising_edge(MATCH_PRO)then
STATE_IP <= '1';
end if;
if RESET_IP = '1' then
STATE_IP <= '0';
end if;
end process;
IP : process(RX_CLK,STATE_IP,COUNT_IP,RECOUNT_IP,RX_IP)
begin
if rising_edge(RX_CLK)then
if STATE_IP ='1' then
if RECOUNT_IP = '0' then
if COUNT_IP < 11 then
COUNT_IP <= COUNT_IP + 1;
else
RECOUNT_IP <= '1';
COUNT_IP <= 1;
end if;
else
if COUNT_IP = 9 then
if RX_IP = FIX_IP then
MATCH_IP <= '1';
end if;
RESET_IP <= '1';
COUNT_IP <= 1;
RECOUNT_IP <= '0';
else
RX_IP((COUNT_IP*4)-4) <= RX_DATA(0);
RX_IP((COUNT_IP*4)-3) <= RX_DATA(1);
RX_IP((COUNT_IP*4)-2) <= RX_DATA(2);
RX_IP((COUNT_IP*4)-1) <= RX_DATA(3);
COUNT_IP <= COUNT_IP + 1;
end if;
end if;
else
MATCH_IP <= '0';
RESET_IP <= '0';
RX_IP <= (others => '0');
end if;
end if;
end process;
--CHECK IF THE DESTINATION DESTINATION PORT USED IN THE RECEIVED PACKET
--BELONGS TO THE FPGA RECEIVER (3435)
PORT_ON:process(MATCH_IP,RESET_PORT)
begin
if rising_edge(MATCH_IP)then
STATE_PORT <= '1';
end if;
if RESET_PORT = '1' then
STATE_PORT <= '0';
end if;
end process;
DST_PORT : process(RX_CLK,STATE_PORT,COUNT_PORT,RECOUNT_PORT,RX_PORT)
begin
if rising_edge(RX_CLK)then
if STATE_PORT ='1' then
if RECOUNT_PORT = '0' then
if COUNT_PORT < 3 then
COUNT_PORT <= COUNT_PORT + 1;
else
RECOUNT_PORT <= '1';
COUNT_PORT <= 1;
end if;
else
if COUNT_PORT = 5 then
if RX_PORT = FIX_PORT then
MATCH_PORT <= '1';
44
end if;
RESET_PORT <= '1';
COUNT_PORT <= 1;
RECOUNT_PORT <= '0';
else
RX_PORT((COUNT_PORT*4)-4) <= RX_DATA(0);
RX_PORT((COUNT_PORT*4)-3) <= RX_DATA(1);
RX_PORT((COUNT_PORT*4)-2) <= RX_DATA(2);
RX_PORT((COUNT_PORT*4)-1) <= RX_DATA(3);
COUNT_PORT <= COUNT_PORT + 1;
end if;
end if;
else
MATCH_PORT <= '0';
RESET_PORT <= '0';
RX_PORT <= (others => '0');
end if;
end if;
end process;
end Behavioral;
45
A.4 BUFFER
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:04:38 10/18/4507
-- Design Name:
-- Module Name: BUFF - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity BUFF is
port(RX_CLK,
REQUEST,
DAC_ON,
BUFF_EN : in STD_LOGIC;
CLK_50MHZ: in std_logic;
RX_DATA : in STD_LOGIC_VECTOR(0 to 3);
LED_BUFF,
DAC_EN : out STD_LOGIC;
DATA_OUT : out STD_LOGIC_VECTOR(7 downto 0)
);
end BUFF;
architecture Behavioral of BUFF is
component RAMS is
port( CLK_W: in std_logic;
CLK_R: in std_logic;
--EN : in std_logic;
--RST: in std_logic;
WRITE : in std_logic_vector(3 downto 0);
READ : in std_logic_vector(3 downto 0);
AD_W : in std_logic_vector(7 downto 0);
AD_R : in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end component;
type HOLDER_TYPE is array (0 to 3) of std_logic_vector (7 downto 0);
signal HOLDER : HOLDER_TYPE := (others => "00000000"); --a temporary holder of the data received, collect
nibbles and form it as bytes
signal WRITE : std_logic_vector(3 downto 0):= "1111"; --determines which of the ram is active
signal READ : std_logic_vector(3 downto 0):= "1111"; --determines which of the ram is active
signal AD_W : std_logic_vector(7 downto 0):= "11111110"; --addess of a slot in a ram to be written
signal AD_R : std_logic_vector(7 downto 0):= "11111111"; --addess of a slot in a ram to be read
signal DI : std_logic_vector(7 downto 0):= "00000000"; --the Data Input to the ram
signal DO : std_logic_vector(7 downto 0):= "00000000"; --data read from the ram
signal STATE_BUFF : std_logic:= '0'; -- state of the buffer module
signal OFF_BUFF : std_logic:= '0'; -- turns off the buffer module if set to high
46
signal ENABLE_DAC : std_logic:= '0'; -- turns on the buffer module
signal STOP_SKIP : std_logic:= '0'; -- indicates the end of the skip, and start of the saving of the
incoming nibbles
signal CLK_W : std_logic:= '0'; -- clock used by the ram
signal CLK_W_ADJST: std_logic:= '0'; -- clock used to adjust the block and address of ram to be written
signal CLK_R : std_logic:= '0'; -- clock used for reading the ram
signal SKIP_COUNT : integer range 1 to 200:= 1; --counter for the nibbles to skipped
signal WIDTH : integer range 1 to 2 := 1; --a factor for the width of the holder
signal DEPTH : integer range 0 to 3 := 2; --the depth of the holder array
signal H_DEPTH : integer range 0 to 3 := 1; --used to index the holder's depth
signal COUNT_BYTE : integer range 0 to 1000:= 1; --counts the number of bytes from a single packet written to the ram
signal COUNT_50MHZ: integer range 0 to 128:= 0; --counts the number of rising edges of 50MHZ clock before clk_r
rises
signal COUNT_BUFF : integer range 0 to 128:= 1; --counts the number of buffers received
constant SAMPLING_RATE : integer range 100 to 50000:= 48000;-- sampling rate
constant SAMPLE_LENGTH : integer range 10 to 100 := 100; -- sampling length (ms)
constant BUFF_NUM : integer range 5 to 10 := 10; -- number of buffers
used
procedure BUFFSIZE(SAMPLING_RATE,SAMPLE_LENGTH,BUFF_NUM: in integer range 0 to 50000;
BYTE_LIMIT : out integer range 0 to 1000)
is
begin
BYTE_LIMIT :=((SAMPLING_RATE/1000)*(SAMPLE_LENGTH/BUFF_NUM));
end procedure;
shared variable BYTE_LIMIT: integer range 0 to 1000;
begin
DAC_EN <= ENABLE_DAC;
DATA_OUT <= DO;
LED_BUFF <= STATE_BUFF;
RAM_BLOCK : RAMS
port map ( CLK_W => CLK_W,
CLK_R => CLK_R,
-- EN => STATE_BUFF,
-- RST : in std_logic;
WRITE => WRITE,
READ => READ,
AD_R => AD_R,
AD_W => AD_W,
DI => DI,
DO => DO
);
BUFFSIZE(SAMPLING_RATE,SAMPLE_LENGTH,BUFF_NUM,BYTE_LIMIT);
STATUS : process(BUFF_EN,OFF_BUFF)
begin
if OFF_BUFF = '1' then
STATE_BUFF <= '0';
elsif rising_edge(BUFF_EN)then
STATE_BUFF <= '1';
end if;
end process;
SAVE : process(RX_CLK)
begin
if rising_edge(RX_CLK)then
if STATE_BUFF='1' then
if STOP_SKIP = '0' then
if SKIP_COUNT < 117 then
SKIP_COUNT <= SKIP_COUNT +1;
else
--if SKIP_COUNT > or = 117
STOP_SKIP <= '1';
SKIP_COUNT <= 1;
--restart SKIP_COUNT
WIDTH <= 1;
47
end if;
else
--if STOP_SKIP = '1'
HOLDER(DEPTH)((WIDTH*4)-4) <= RX_DATA(0);
HOLDER(DEPTH)((WIDTH*4)-3) <= RX_DATA(1);
HOLDER(DEPTH)((WIDTH*4)-2) <= RX_DATA(2);
HOLDER(DEPTH)((WIDTH*4)-1) <= RX_DATA(3);
if WIDTH = 1 then
WIDTH <= WIDTH + 1;
CLK_W <= '1';
CLK_W_ADJST <= '0';
else
WIDTH <= WIDTH - 1;
CLK_W <= '0';
CLK_W_ADJST <= '1';
if (COUNT_BYTE = BYTE_LIMIT) then
STOP_SKIP <= '0';
COUNT_BYTE <= 1;
OFF_BUFF <= '1';
-- if DAC_ON = '1' then
ENABLE_DAC <= '1';
-- else
-- if (COUNT_BUFF = 2*BUFF_NUM) then -
- delay
-- ENABLE_DAC <= '1';
-- COUNT_BUFF <= 1;
-- else
-- COUNT_BUFF <=
COUNT_BUFF +1;
-- ENABLE_DAC <= '0';
-- end if;
-- end if;
else
COUNT_BYTE <= COUNT_BYTE +1;
end if;
end if;
end if;
else
STOP_SKIP <= '0';
ENABLE_DAC <= '0';
OFF_BUFF <= '0';
CLK_W <= '1';
end if;
end if;
end process;
WRITE_to_DI : process(CLK_W_ADJST, STATE_BUFF)
begin
-- if STATE_BUFF = '0' then
-- case DEPTH is
-- when 0 => DEPTH <= DEPTH + 3;
-- when others => DEPTH <= DEPTH - 1;
-- end case;
-- case H_DEPTH is
-- when 0 => H_DEPTH <= H_DEPTH + 1;
-- when others => H_DEPTH <= H_DEPTH - 1;
-- end case;
if rising_edge(CLK_W_ADJST) then
DI <= HOLDER(H_DEPTH);
case AD_W is
when "11111111" => AD_W <= "00000000";
case WRITE is
when "1111" => WRITE <= "0000";
when others => WRITE <= WRITE + "0001";
end case;
when others => AD_W <= AD_W + "00000001";
end case;
48
case DEPTH is
when 3 => H_DEPTH <= DEPTH;
DEPTH <= 0;
when others => H_DEPTH <= DEPTH;
DEPTH <= DEPTH +1;
end case;
end if;
end process;
ADDR_ADJST : process(REQUEST)--adjust the ram address and ram block to be read
begin
if rising_edge(REQUEST) then
case AD_R is
when "11111111" =>
AD_R <= "00000000";
case READ is
when "1111" => READ <= "0000";
when others => READ <= READ + "0001";
end case;
when others =>
AD_R <= AD_R + "00000001";
end case;
end if;
end process;
LOAD : process(CLK_50MHZ) --derive a clock for reading the RAM
begin
if rising_edge(CLK_50MHZ) then
if REQUEST = '1' then
if COUNT_50MHZ = 100 then
CLK_R <= '1';
else
COUNT_50MHZ <= COUNT_50MHZ+1;
end if;
else
COUNT_50MHZ <= 0;
CLK_R <= '0';
end if;
end if;
end process;
end Behavioral;
49
A.4.1 RAMS ----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 22:12:23 12/13/2007
-- Design Name:
-- Module Name: RAMS - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity RAMS is
port(
CLK_W: in std_logic;
CLK_R: in std_logic;
--EN : in std_logic;
--RST: in std_logic;
WRITE: in std_logic_vector(3 downto 0);
READ : in std_logic_vector(3 downto 0);
AD_W : in std_logic_vector(7 downto 0);
AD_R: in std_logic_vector(7 downto 0);
DI : in std_logic_vector(7 downto 0);
DO : out std_logic_vector(7 downto 0)
);
end;
architecture Behavioral of RAMS is
component RAM is
port (clk_w : in std_logic;
clk_r : in std_logic;
we : in std_logic;
re : in std_logic;
ad_w : in std_logic_vector(7 downto 0);
ad_r: in std_logic_vector(7 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0));
end component;
signal DO0 : std_logic_vector(7 downto 0):= "00000000";
signal DO1 : std_logic_vector(7 downto 0):= "00000000";
signal DO2 : std_logic_vector(7 downto 0):= "00000000";
signal DO3 : std_logic_vector(7 downto 0):= "00000000";
signal DO4 : std_logic_vector(7 downto 0):= "00000000";
signal DO5 : std_logic_vector(7 downto 0):= "00000000";
signal DO6 : std_logic_vector(7 downto 0):= "00000000";
signal DO7 : std_logic_vector(7 downto 0):= "00000000";
signal DO8 : std_logic_vector(7 downto 0):= "00000000";
signal DO9 : std_logic_vector(7 downto 0):= "00000000";
signal DO10: std_logic_vector(7 downto 0):= "00000000";
signal DO11: std_logic_vector(7 downto 0):= "00000000";
signal DO12: std_logic_vector(7 downto 0):= "00000000";
signal DO13: std_logic_vector(7 downto 0):= "00000000";
50
signal DO14: std_logic_vector(7 downto 0):= "00000000";
signal DO15: std_logic_vector(7 downto 0):= "00000000";
signal RE : std_logic_vector(15 downto 0):= "0000000000000000";
signal WE : std_logic_vector(15 downto 0):= "0000000000000000";
begin
B0: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(0),re => RE(0), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO0(7 downto 0));
B1: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(1),re => RE(1), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO1(7 downto 0));
B2: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(2),re => RE(2), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO2(7 downto 0));
B3: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(3),re => RE(3), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO3(7 downto 0));
B4: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(4),re => RE(4), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO4(7 downto 0));
B5: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(5),re => RE(5), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO5(7 downto 0));
B6: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(6),re => RE(6), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO6(7 downto 0));
B7: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(7),re => RE(7), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO7(7 downto 0));
B8: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(8),re => RE(8), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO8(7 downto 0));
B9: RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(9),re => RE(9), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO9(7 downto 0));
B10:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(10),re => RE(10), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO10(7 downto 0));
B11:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(11),re => RE(11), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO11(7 downto 0));
B12:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(12),re => RE(12), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO12(7 downto 0));
B13:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(13),re => RE(13), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO13(7 downto 0));
B14:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(14),re => RE(14), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO14(7 downto 0));
B15:RAM port map( clk_w => CLK_W, clk_r => CLK_R, we => WE(15),re => RE(15), di => DI(7 downto 0), ad_w=>
AD_W(7 downto 0), ad_r=> AD_R(7 downto 0), do => DO15(7 downto 0));
with READ select
DO <= DO0 when "0000",
DO1 when "0001",
DO2 when "0010",
DO3 when "0011",
DO4 when "0100",
DO5 when "0101",
DO6 when "0110",
DO7 when "0111",
DO8 when "1000",
DO9 when "1001",
DO10 when "1010",
DO11 when "1011",
DO12 when "1100",
DO13 when "1101",
DO14 when "1110",
DO15 when "1111",
"00000000" when others;
with READ select
RE <= "0000000000000001" when "0000",
"0000000000000010" when "0001",
"0000000000000100" when "0010",
"0000000000001000" when "0011",
"0000000000010000" when "0100",
"0000000000100000" when "0101",
"0000000001000000" when "0110",
"0000000010000000" when "0111",
"0000000100000000" when "1000",
"0000001000000000" when "1001",
"0000010000000000" when "1010",
51
"0000100000000000" when "1011",
"0001000000000000" when "1100",
"0010000000000000" when "1101",
"0100000000000000" when "1110",
"1000000000000000" when "1111",
"0000000000000000" when others;
with WRITE select
WE <= "0000000000000001" when "0000",
"0000000000000010" when "0001",
"0000000000000100" when "0010",
"0000000000001000" when "0011",
"0000000000010000" when "0100",
"0000000000100000" when "0101",
"0000000001000000" when "0110",
"0000000010000000" when "0111",
"0000000100000000" when "1000",
"0000001000000000" when "1001",
"0000010000000000" when "1010",
"0000100000000000" when "1011",
"0001000000000000" when "1100",
"0010000000000000" when "1101",
"0100000000000000" when "1110",
"1000000000000000" when "1111",
"0000000000000000" when others;
end Behavioral;
52
A.4.1.1 RAM ----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:34:29 12/13/2007
-- Design Name:
-- Module Name: RAM - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity RAM is
port (clk_w : in std_logic;
clk_r : in std_logic;
we : in std_logic;
re : in std_logic;
ad_w: in std_logic_vector(7 downto 0);
ad_r: in std_logic_vector(7 downto 0);
di : in std_logic_vector(7 downto 0);
do : out std_logic_vector(7 downto 0));
end RAM;
architecture Behavioral of RAM is
type ram_type is array (255 downto 0) of std_logic_vector (7 downto 0);
signal RAM : ram_type:= (others => "00000000");
begin
process (clk_w)
begin
if rising_edge(clk_w) then
if (we = '1') then
RAM(conv_integer(ad_w)) <= di;
end if;
end if;
end process;
process(clk_r)
begin
if rising_edge(clk_r) then
if (re = '1') then
do <= RAM(conv_integer(ad_r));
end if;
end if;
end process;
end Behavioral;
53
A.5 DAC
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 01:14:30 10/19/2007
-- Design Name:
-- Module Name: DAC - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaation if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DAC is
port(DAC_EN,
CLK_50MHZ : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
SPI_MOSI,
SPI_SCK,
DAC_CLR,
LED_DAC,
REQUEST,
DAC_ON,
DAC_CS : out std_logic
);
end DAC;
architecture Behavioral of DAC is
signal STATE_DAC : std_logic := '0';
signal CLK_REQ : std_logic := '0';
signal CLK_READ : std_logic := '0';
signal CLK_CS : std_logic := '1';
signal CLK_DATA : std_logic := '0';
signal CLK_SPI : std_logic := '0';
signal RECOUNT : std_logic := '0';
-- signal OFF_STATE : std_logic := '0'; --turns off the state if enabled
signal DECREMENT : std_logic := '0'; --enable decrement array
-- signal DEC_BUFF_TOBE_READ : std_logic := '0'; --decrement array
signal DATA_OUT : std_logic := '0'; --output serial data to DAC chip
signal MINI_BUFF : std_logic_vector (0 to 31):= "00000000001111110000000000000000";
signal SIGN : std_logic := '0'; -- MSB of
the received data, refers to the sign
signal SEG : std_logic_vector (2 downto 0) := "000"; --3-bit segment identifier, next to the SIGN
bit
signal MAG : std_logic_vector (3 downto 0) := "0000";--4-bit magnitude
signal COUNT_50MHZ : integer range 0 to 7000 := 1; --counts
the number of rising edge of 50MHZ clk
signal COUNT_BYTE : integer range 0 to 1000 := 1; --used for
accessing the input array
signal INDEX_MINIBUFF: integer range 0 to 31 := 0; --used for indexing the mini buffer
54
signal COUNT_BUFF : integer range 0 to 50 := 0; --
determines the number of buffers filled
constant SAMPLING :integer range 8000 to 48000 := 48000; --(samples per second)
constant SAMPLE_LENGTH :integer range 10 to 100 := 20; --sampling length (ms)
constant BUFF_NUM : integer range 0 to 10 := 5; --number of buffers used
procedure CALCULATE(SAMPLING,SAMPLE_LENGTH,BUFF_NUM : in integer range 0 to 48000; --
process(CLK_50MHZ)
HIGH_CS,LOW_CS_EXTRA,UP_DATA_CLK,UP_SCK,DOWN_DATA_CLK,DOWN_SCK,BYTE_LIMIT : out integer range 0 to
7000) is
variable PERIOD_CS,H_C,PERIOD_SCK,U_D_C,U_S,D_D_C :integer range 0 to 7000;
begin
PERIOD_CS := (50000000/SAMPLING); -- one period of DAC_CS
HIGH_CS := ((PERIOD_CS/2)+(PERIOD_CS mod 2)); -- number of rising edges of 50MHz clk
when DAC_CS is High
H_C := ((PERIOD_CS/2));
PERIOD_SCK := ((H_C)/32); -- number of rising edges indicating 1 period of data_clk and SPI_SCK
clocks
LOW_CS_EXTRA := ((H_C mod 32)+(PERIOD_SCK mod 4)); -- extra rising edges alloted for data request
and preconditioning
UP_DATA_CLK := (PERIOD_SCK/4);
-- counts before data_clk signal gets to high
U_D_C := (PERIOD_SCK/4);
UP_SCK := (U_D_C + (PERIOD_SCK/4)); -- counts
before SPI_SCK signal gets to high
U_S := (U_D_C + (PERIOD_SCK/4));
DOWN_DATA_CLK := (U_S + (PERIOD_SCK/4)); -- counts
before data_clk signal gets to low
D_D_C := (U_S + (PERIOD_SCK/4));
DOWN_SCK := (D_D_C + (PERIOD_SCK/4)); -- counts
before SPI_SCK signal gets to low
BYTE_LIMIT := ((SAMPLING*SAMPLE_LENGTH)/(1000*BUFF_NUM)); -- number of bytes in a
single packet
end procedure;
shared variable HIGH_CS : integer range 1 to 7000;
shared variable LOW_CS_EXTRA : integer range 1 to 50; -- extra rising edges alloted for
data request and preconditioning and DSP
shared variable UP_SCK : integer range 1 to 100; -- number of rising edges of
50MHz clk before SPI_SCK signal goes high
shared variable DOWN_SCK : integer range 1 to 100; -- number of rising edges of
50MHz clk before SPI_SCK signal goes low
shared variable UP_DATA_CLK : integer range 1 to 100; -- number of rising edges of 50MHz clk
before data_clk signal goes high
shared variable DOWN_DATA_CLK : integer range 1 to 100; -- number of rising edges of
50MHz clk before data_clk signal goes low
shared variable BYTE_LIMIT : integer range 1 to 1000; -- size of one buffer
begin
SPI_MOSI<= DATA_OUT;
SPI_SCK <= CLK_SPI;
LED_DAC <= STATE_DAC;
DAC_ON <= STATE_DAC;
DAC_CLR <= STATE_DAC;
DAC_CS <= CLK_CS;
REQUEST <= CLK_REQ;
CALCULATE(SAMPLING,SAMPLE_LENGTH,BUFF_NUM,HIGH_CS,LOW_CS_EXTRA,
UP_DATA_CLK,UP_SCK,DOWN_DATA_CLK,DOWN_SCK,BYTE_LIMIT );
--MONITOR THE NUMBER OF BUFFERS TO BE PROCESSED
COUNTER_BUFF : process(DAC_EN,DECREMENT,STATE_DAC)
begin
if DECREMENT = '1' then
COUNT_BUFF <= (COUNT_BUFF - 1);
elsif rising_edge(DAC_EN)then
if STATE_DAC = '0' then
COUNT_BUFF <= (COUNT_BUFF + (2*BUFF_NUM));
else
COUNT_BUFF <= (COUNT_BUFF + 1);
55
end if;
end if;
end process;
--TURN ON OR OFF THE DAC MODULE
STATUS : process(CLK_50MHZ)
begin
if rising_edge(CLK_50MHZ)then
if COUNT_BUFF < 1 then
STATE_DAC <= '0';
else
STATE_DAC <= '1';
end if;
end if;
end process;
--DERIVE THE CLOCKS NECESSARY FOR DAC CHIP TO WORK
CLOCKS : process(CLK_50MHZ)
begin
if rising_edge(CLK_50MHZ)then
if STATE_DAC = '1' then
if CLK_CS = '1' then
CLK_REQ <= '1';
if COUNT_50MHZ < HIGH_CS then
COUNT_50MHZ <= COUNT_50MHZ +1;
else
CLK_CS <= '0';
COUNT_50MHZ <= 1;
CLK_READ <= '1';
end if;
-- if COUNT_BUFF < 1 then
-- OFF_STATE <= '1';
-- else
-- OFF_STATE <= '0';
-- end if;
else
CLK_REQ <= '0';
if RECOUNT = '0' then
if COUNT_50MHZ < LOW_CS_EXTRA then
COUNT_50MHZ <= COUNT_50MHZ + 1;
else
RECOUNT <= '1';
COUNT_50MHZ <= 1;
end if;
else
COUNT_50MHZ <= COUNT_50MHZ + 1;
if COUNT_50MHZ = UP_DATA_CLK then
CLK_DATA <= '1';
elsif COUNT_50MHZ = UP_SCK then
CLK_SPI <= '1';
elsif COUNT_50MHZ = DOWN_DATA_CLK then
CLK_DATA <= '0';
elsif COUNT_50MHZ = DOWN_SCK then
CLK_SPI <= '0';
COUNT_50MHZ <= 1;
if INDEX_MINIBUFF < 31 then
INDEX_MINIBUFF <=
INDEX_MINIBUFF+1;
else
CLK_READ <= '0';
CLK_CS <= '1';
CLK_DATA <= '0';
CLK_SPI <= '0';
RECOUNT <= '0';
INDEX_MINIBUFF <= 0;
end if;
end if;
end if;
end if;
else
CLK_REQ <= '0';
56
CLK_READ <= '0';
CLK_CS <= '1';
CLK_DATA <= '0';
CLK_SPI <= '0';
INDEX_MINIBUFF <= 0;
COUNT_50MHZ <= 1;
RECOUNT <= '0';
-- OFF_STATE <= '0';
end if;
end if;
end process;
--MONITORS THE NUMBER OF BYTES BEING CONVERTED TO ANALOG
COUNT_DATA: process(DECREMENT,CLK_CS,COUNT_BYTE)
begin
if DECREMENT = '1' then
DECREMENT <= '0';
COUNT_BYTE <= 1;
elsif rising_edge(CLK_CS) then
if COUNT_BYTE = BYTE_LIMIT then
COUNT_BYTE <= 1;
DECREMENT <= '1';
else
DECREMENT <= '0';
COUNT_BYTE <= COUNT_BYTE+1;
end if;
end if;
end process;
--ACCEPT THE DATA FROM THE BUFFER MODULE
LOAD : process(CLK_READ)
begin
if rising_edge(CLK_READ) then
SIGN <= DATA_IN(7);
SEG(2) <= DATA_IN(6);
SEG(1) <= DATA_IN(5);
SEG(0) <= DATA_IN(4);
MAG(3) <= DATA_IN(3);
MAG(2) <= DATA_IN(2);
MAG(1) <= DATA_IN(1);
MAG(0) <= DATA_IN(0);
end if;
end process;
--DIGITAL SIGNAL PROCESSING
EXPAND : process(SIGN,SEG,MAG)
begin
case SEG is
when "000" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 23 => '0',
24 => MAG(3),25 => MAG(2),
26 => MAG(1),27 => MAG(0),
others => '0');
when "001" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 22 => '0',23 =>'1',
24 => MAG(3),25 => MAG(2),
26 => MAG(1),27 => MAG(0),
others => '0');
when "010" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 21 => '0',22 =>'1',
23 => MAG(3),24 => MAG(2),
25 => MAG(1),26 => MAG(0),27 =>'1',
others => '0');
when "011" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 20 => '0',21 =>'1',
22 => MAG(3),23 => MAG(2),
24 => MAG(1),25 => MAG(0),26 =>'1',
others => '0');
57
when "100" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 19 => '0',20 =>'1',
21 => MAG(3),22 => MAG(2),
23 => MAG(1),24 => MAG(0),25 =>'1',
others => '0');
when "101" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 to 18 => '0',19 =>'1',
20 => MAG(3),21 => MAG(2),
22 => MAG(1),23 => MAG(0),24 =>'1',
others => '0');
when "110" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 => '0',18 =>'1',
19 => MAG(3),20 => MAG(2),
21 => MAG(1),22 => MAG(0),23 =>'1',
others => '0');
when "111" => MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
16 => SIGN, 17 => '1',
18 => MAG(3),19 => MAG(2),
20 => MAG(1),21 => MAG(0),22 =>'1',
others => '0');
when others => MINI_BUFF <= (0 to 9 => '0', 10 to 15 => '1',
others => '0');
end case;
end process;
-- EXPAND : process(SIGN,SEG,MAG)
-- begin
-- MINI_BUFF <= (0 to 9 => '0',10 to 15 => '1',
-- 16 => SIGN, 17 => SEG(2),
-- 18 => SEG(1),19 => SEG(0),
-- 20 => MAG(3),21 => MAG(2),
-- 22 => MAG(1),23 => MAG(0),
-- others => '0');
-- end process;
--OUTPUT THE DATA SERIALLY TO THE DAC CHIP
READ_DATA : process(CLK_DATA)
begin
if rising_edge(CLK_DATA)then
if STATE_DAC = '1' then
DATA_OUT <= MINI_BUFF(INDEX_MINIBUFF);
end if;
end if;
end process;
end Behavioral;
58
Appendix B: TESTBENCHES
B.1: EPAS TOP MODULE
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:25:06 01/17/2008
-- Design Name: EPAS_top
-- Module Name: D:/docs/acad/ryan/epas/EPAS/SOURCE_CODES/TESTBENCH/TOP_TB.vhd
-- Project Name: EPAS
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: EPAS_top
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY TOP_TB_vhd IS
END TOP_TB_vhd;
ARCHITECTURE behavior OF TOP_TB_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT EPAS_top
PORT(
RX_CLK : IN std_logic;
CLK_50MHZ : IN std_logic;
RX_DV : IN std_logic;
RX_DATA : IN std_logic_vector(0 to 3);
SPI_MOSI : OUT std_logic;
SPI_SCK : OUT std_logic;
LED_BUFF,
LED_DAC,
DAC_CLR : OUT std_logic;
DAC_CS : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL RX_CLK : std_logic := '0';
SIGNAL CLK_50MHZ : std_logic := '0';
SIGNAL RX_DV : std_logic := '0';
SIGNAL RX_DATA : std_logic_vector(0 to 3) := (others=>'0');
--Outputs
SIGNAL SPI_MOSI : std_logic;
59
SIGNAL SPI_SCK : std_logic;
SIGNAL DAC_CLR : std_logic;
SIGNAL LED_BUFF : std_logic;
SIGNAL LED_DAC : std_logic;
SIGNAL DAC_CS : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: EPAS_top PORT MAP(
RX_CLK => RX_CLK,
CLK_50MHZ => CLK_50MHZ,
RX_DV => RX_DV,
RX_DATA => RX_DATA,
SPI_MOSI => SPI_MOSI,
SPI_SCK => SPI_SCK,
LED_BUFF => LED_BUFF,
LED_DAC => LED_DAC,
DAC_CLR => DAC_CLR,
DAC_CS => DAC_CS
);
tb1 : PROCESS
BEGIN
RX_CLK <= '0', '1' after 20 ns;
wait for 40 ns;
END PROCESS;
tb2 : PROCESS
BEGIN
CLK_50MHZ <= '0', '1' after 10 ns;
wait for 20 ns;
END PROCESS;
tb3: PROCESS
BEGIN
RX_DV <= '1','0' after 640 ns, '0' after 700 ns,
'1' after 26200 ns,'0' after 26250 ns,
'1' after 52400 ns, '0' after 52450 ns,
'1' after 78600 ns, '0' after 78650 ns,
'1' after 104800 ns, '0' after 104850 ns;
wait for 40 ms;
END PROCESS;
tb4: PROCESS
BEGIN
RX_DATA <= "1010", "1011" after 600 ns, --preamble(8bytes)
"1111" after 640 ns, "1111" after 680 ns,--Dst MAC address(6bytes)
"1111" after 720 ns, "1111" after 760 ns,
"1111" after 800 ns, "1111" after 840 ns,
"1111" after 880 ns, "1111" after 920 ns,
"1111" after 960 ns, "1111" after 1000 ns,
"1111" after 1040 ns, "1111" after 1080 ns,
"0000" after 1120 ns, "0000" after 1160 ns,--src MAC address(6bytes)
"0001" after 1200 ns, "0010" after 1240 ns,
"0011" after 1280 ns, "0100" after 1320 ns,
"0101" after 1360 ns, "0110" after 1400 ns,
"0111" after 1440 ns, "1000" after 1480 ns,
"1001" after 1520 ns, "1010" after 1560 ns,
"0001" after 1600 ns, "0000" after 1640 ns,--ethernet type(IP)(2bytes)
"0000" after 1680 ns, "0000" after 1720 ns,
"0001" after 1760 ns, "0010" after 1800 ns,--IP Header(9bytes)
"0011" after 1840 ns, "0100" after 1880 ns,
"0101" after 1920 ns, "0110" after 1960 ns,
"0111" after 2000 ns, "1000" after 2040 ns,
"1001" after 2080 ns, "1010" after 2120 ns,
"1011" after 2160 ns, "1100" after 2200 ns,
"1101" after 2240 ns, "1110" after 2280 ns,
"1111" after 2320 ns, "0000" after 2360 ns,
"0001" after 2400 ns, "0010" after 2440 ns,
60
"1000" after 2480 ns, "1000" after 2520 ns,--IPProtocol(UDP)(1byte)
"1111" after 2560 ns, "1111" after 2600 ns,--Checksum(2bytes)
"1111" after 2640 ns, "1111" after 2680 ns,
"0011" after 2720 ns, "1111" after 2760 ns,--SRC_IPAddress(4bytes)
"0111" after 2800 ns, "1010" after 2840 ns,
"1111" after 2880 ns, "1110" after 2920 ns,
"1111" after 2960 ns, "1111" after 3000 ns,
"1111" after 3040 ns, "1111" after 3080 ns,--DST_address(4bytes)
"1111" after 3120 ns, "1111" after 3160 ns,
"1111" after 3200 ns, "1111" after 3240 ns,
"1111" after 3280 ns, "1111" after 3320 ns,
"0111" after 3360 ns, "1010" after 3400 ns,--SRC_port(2bytes)
"1111" after 3440 ns, "1110" after 3480 ns,
"1011" after 3520 ns, "0000" after 3560 ns,--DST_port(2Bytes)
"1101" after 3600 ns, "0110" after 3640 ns,
"0111" after 3680 ns, "1010" after 3720 ns,--UPD length(2Bytes)
"1111" after 3760 ns, "1110" after 3800 ns,
"1111" after 3840 ns, "1111" after 3880 ns,--UDP Checksum)(2bytes)
"1111" after 3920 ns, "1111" after 3960 ns,
"0000" after 4000 ns, "1111" after 4040 ns,--UDP Payload (PCM header)
"0000" after 4080 ns, "0000" after 4120 ns,
"1000" after 4160 ns, "0000" after 4200 ns,
"0100" after 4240 ns, "0000" after 4280 ns,
"1100" after 4320 ns, "0000" after 4360 ns,
"0010" after 4400 ns, "0000" after 4440 ns,
"1010" after 4480 ns, "0000" after 4520 ns,
"0110" after 4560 ns, "0000" after 4600 ns,
"1110" after 4640 ns, "0000" after 4680 ns,
"0001" after 4720 ns, "0000" after 4760 ns,--10
"1001" after 4800 ns, "0000" after 4840 ns,
"0101" after 4880 ns, "0000" after 4920 ns,
"1101" after 4960 ns, "0000" after 5000 ns,
"0011" after 5040 ns, "0000" after 5080 ns,
"1011" after 5120 ns, "0000" after 5160 ns,
"0111" after 5200 ns, "0000" after 5240 ns,
"1111" after 5280 ns, "0000" after 5320 ns,
"0000" after 5360 ns, "1000" after 5400 ns,
"1000" after 5440 ns, "1000" after 5480 ns,
"0100" after 5520 ns, "1000" after 5560 ns,--20
"1100" after 5600 ns, "1000" after 5640 ns,
"0010" after 5680 ns, "1000" after 5720 ns,
"1010" after 5760 ns, "1000" after 5800 ns,
"0110" after 5840 ns, "1000" after 5880 ns,
"1110" after 5920 ns, "1000" after 5960 ns,
"0001" after 6000 ns, "1000" after 6040 ns,
"1001" after 6080 ns, "1000" after 6120 ns,
"0101" after 6160 ns, "1000" after 6200 ns,
"1101" after 6240 ns, "1000" after 6280 ns,
"0011" after 6320 ns, "1000" after 6360 ns,--30
"1011" after 6400 ns, "1000" after 6440 ns,
"1000" after 6480 ns, "1000" after 6520 ns,
"1111" after 6560 ns, "1111" after 6600 ns,
"1111" after 6640 ns, "1111" after 6680 ns,
"0011" after 6720 ns, "1111" after 6760 ns,
"0111" after 6800 ns, "1010" after 6840 ns,
"1111" after 6880 ns, "1110" after 6920 ns,
"1111" after 6960 ns, "1111" after 7000 ns,
"1111" after 7040 ns, "1111" after 7080 ns,
"1111" after 7120 ns, "1111" after 7160 ns,
"1111" after 7200 ns, "1111" after 7240 ns,
"1111" after 7280 ns, "1111" after 7320 ns,
"0111" after 7360 ns, "1010" after 7400 ns,
"1010" after 7440 ns, "1010" after 7480 ns,
"1100" after 7520 ns, "0000" after 7560 ns,-- VOICE DATA
"0010" after 7600 ns, "0000" after 7640 ns,--4
"1010" after 7680 ns, "0000" after 7720 ns,--5
"0110" after 7760 ns, "0000" after 7800 ns,--6
"1110" after 7840 ns, "0000" after 7880 ns,--7
"0001" after 7920 ns, "0000" after 7960 ns,--8
"1001" after 8000 ns, "0000" after 8040 ns,--9
61
"0000" after 8080 ns, "0000" after 8120 ns,--0
"1000" after 8160 ns, "0000" after 8200 ns,--1
"0100" after 8240 ns, "0000" after 8280 ns,--2
"1100" after 8320 ns, "0000" after 8360 ns,--3
"0010" after 8400 ns, "0000" after 8440 ns,--4
"1010" after 8480 ns, "0000" after 8520 ns,--5
"0110" after 8560 ns, "0000" after 8600 ns,--6
"1110" after 8640 ns, "0000" after 8680 ns,--7
"0001" after 8720 ns, "0000" after 8760 ns,--8
"1001" after 8800 ns, "0000" after 8840 ns,--9
"0101" after 8880 ns, "0000" after 8920 ns,--10
"1101" after 8960 ns, "0000" after 9000 ns,--11
"0011" after 9040 ns, "0000" after 9080 ns,--12
"1011" after 9120 ns, "0000" after 9160 ns,--13
"0111" after 9200 ns, "0000" after 9240 ns,--14
"1111" after 9280 ns, "0000" after 9320 ns,--15
"0000" after 9360 ns, "1000" after 9400 ns,--16
"1000" after 9440 ns, "1000" after 9480 ns,--17
"0100" after 9520 ns, "1000" after 9560 ns,--18
"1100" after 9600 ns, "1000" after 9640 ns,--19
"0010" after 9680 ns, "1000" after 9720 ns,--20
"1010" after 9760 ns, "1000" after 9800 ns,--21
"0110" after 9840 ns, "1000" after 9880 ns,--22
"1110" after 9920 ns, "1000" after 9960 ns,--23
"0001" after 10000 ns, "1000" after 10040 ns,--24
"1001" after 10080 ns, "1000" after 10120 ns,--25
"0101" after 10160 ns, "1000" after 10200 ns,--26
"1101" after 10240 ns, "1000" after 10280 ns,--27
"0011" after 10320 ns, "1000" after 10360 ns,--28
"1011" after 10400 ns, "1000" after 10440 ns;--29
wait for 26200 ns;
END PROCESS;
END;
62
B.2 SFD DETECTOR
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:27:01 01/17/2008
-- Design Name: SFD_DETECTOR
-- Module Name: D:/docs/acad/ryan/epas/EPAS/SOURCE_CODES/TESTBENCH/SFD_TB.vhd
-- Project Name: EPAS
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: SFD_DETECTOR
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY SFD_TB_vhd IS
END SFD_TB_vhd;
ARCHITECTURE behavior OF SFD_TB_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT SFD_DETECTOR
PORT(
RX_CLK : IN std_logic;
RX_DV : IN std_logic;
RX_DATA : IN std_logic_vector(0 to 3);
AML_EN : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL RX_CLK : std_logic := '0';
SIGNAL RX_DV : std_logic := '0';
SIGNAL RX_DATA : std_logic_vector(0 to 3) := (others=>'0');
--Outputs
SIGNAL AML_EN : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: SFD_DETECTOR PORT MAP(
RX_CLK => RX_CLK,
RX_DV => RX_DV,
RX_DATA => RX_DATA,
AML_EN => AML_EN
);
tb1 : PROCESS
63
BEGIN
RX_CLK <= '0', '1' after 500 ps;
wait for 1 ns;
END PROCESS;
tb2 : PROCESS
BEGIN
RX_DATA <= "1010",
"1011" after 15 ns,
"1111" after 16 ns;
wait for 20 ns;
END PROCESS;
tb3 : PROCESS
BEGIN
RX_DV <= '0', '1' after 20 ns;
wait for 70 ns;
END PROCESS;
END;
64
B.3 ADDRESS MATCHING LOGIC
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:28:20 01/17/2008
-- Design Name: AML
-- Module Name: D:/docs/acad/ryan/epas/EPAS/SOURCE_CODES/TESTBENCH/AML_TB.vhd
-- Project Name: EPAS
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: AML
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY AML_TB_vhd IS
END AML_TB_vhd;
ARCHITECTURE behavior OF AML_TB_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT AML
PORT(
RX_CLK : IN std_logic;
AML_EN : IN std_logic;
RX_DATA : IN std_logic_vector(0 to 3);
BUFF_EN : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL RX_CLK : std_logic := '0';
SIGNAL AML_EN : std_logic := '0';
SIGNAL RX_DATA : std_logic_vector(0 to 3) := (others=>'0');
--Outputs
SIGNAL BUFF_EN : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: AML PORT MAP(
RX_CLK => RX_CLK,
AML_EN => AML_EN,
RX_DATA => RX_DATA,
BUFF_EN => BUFF_EN
);
tb1 : PROCESS
BEGIN
65
RX_CLK <= '1', '0' after 500 fs;
wait for 1 ps;
END PROCESS;
tb2 : PROCESS
BEGIN
AML_EN <= '0', '1' after 16 ps;
wait for 210 ps;
END PROCESS;
tb3 : PROCESS
BEGIN
RX_DATA <= "1010", "1011" after 15 ps, --preamble(8bytes)
"1111" after 16 ps, "1111" after 17 ps,--Dst MAC address(6bytes)
"1111" after 18 ps, "1111" after 19 ps,
"1111" after 20 ps, "1111" after 21 ps,
"1111" after 22 ps, "1111" after 23 ps,
"1111" after 24 ps, "1111" after 25 ps,
"1111" after 26 ps, "1111" after 27 ps,
"0000" after 28 ps, "0000" after 29 ps,--src MAC address(6bytes)
"0001" after 30 ps, "0010" after 31 ps,
"0011" after 32 ps, "0100" after 33 ps,
"0101" after 34 ps, "0110" after 35 ps,
"0111" after 36 ps, "1000" after 37 ps,
"1001" after 38 ps, "0000" after 39 ps,
"0001" after 40 ps, "0000" after 41 ps,--ethernet type(IP)(2bytes)
"0000" after 42 ps, "0000" after 43 ps,
"0111" after 44 ps, "1010" after 45 ps,--IP Header(9bytes)
"1111" after 46 ps, "1110" after 47 ps,
"1111" after 48 ps, "1111" after 49 ps,
"1111" after 50 ps, "1111" after 51 ps,
"0111" after 52 ps, "1010" after 53 ps,
"1111" after 54 ps, "1110" after 55 ps,
"1111" after 56 ps, "1111" after 57 ps,
"1111" after 58 ps, "1111" after 59 ps,
"1111" after 60 ps, "1111" after 61 ps,
"1000" after 62 ps, "1000" after 63 ps,--IPProtocol(UDP)(1byte)
"1111" after 64 ps, "1111" after 65 ps,--Checksum(2bytes)
"1111" after 66 ps, "1111" after 67 ps,
"1111" after 68 ps, "1111" after 69 ps,--SRC_IPAddress(4bytes)
"1111" after 70 ps, "1111" after 71 ps,
"1111" after 72 ps, "1111" after 73 ps,
"1111" after 74 ps, "1111" after 75 ps,
"1111" after 76 ps, "1111" after 77 ps,--DST_address(4bytes)
"1111" after 78 ps, "1111" after 79 ps,
"1111" after 80 ps, "1111" after 81 ps,
"1111" after 82 ps, "1111" after 83 ps,
"0111" after 84 ps, "1010" after 85 ps,--SRC_port(2bytes)
"1111" after 86 ps, "1110" after 87 ps,
"1011" after 88 ps, "0000" after 89 ps,--DST_port(2Bytes)
"1101" after 90 ps, "0110" after 91 ps,
"0111" after 92 ps, "1010" after 93 ps,--UPD length(2Bytes)
"1111" after 94 ps, "1110" after 95 ps,
"1111" after 96 ps, "1111" after 97 ps,--UDP Checksum)(2bytes)
"1111" after 98 ps, "1111" after 99 ps,
"XXXX" after 100 ps, "XXXX" after 187 ps,--UDP Payload (PCM header)
"0000" after 188 ps, "0000" after 189 ps,
"1000" after 190 ps, "0000" after 191 ps,--1
"0100" after 192 ps, "0000" after 193 ps,--2
"1100" after 194 ps, "0000" after 195 ps,--3
"0010" after 196 ps, "0000" after 197 ps,--4
"1010" after 198 ps, "0000" after 199 ps,--5
"0110" after 200 ps, "0000" after 201 ps,--6
"1110" after 202 ps, "0000" after 203 ps,--7
"0001" after 204 ps, "0000" after 205 ps,--8
"1001" after 206 ps, "0000" after 207 ps,--9
"0101" after 208 ps, "0000" after 209 ps;--10
wait for 210 ps;
END PROCESS;
END;
66
B.4 BUFF
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:29:15 01/17/2008
-- Design Name: BUFF
-- Module Name: D:/docs/acad/ryan/epas/EPAS/SOURCE_CODES/TESTBENCH/BUFF_TB.vhd
-- Project Name: EPAS
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: BUFF
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY BUFF_TB_vhd IS
END BUFF_TB_vhd;
ARCHITECTURE behavior OF BUFF_TB_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT BUFF
PORT(
RX_CLK : IN std_logic;
REQUEST : IN std_logic;
BUFF_EN : IN std_logic;
CLK_50MHZ : IN std_logic;
RX_DATA : IN std_logic_vector(0 to 3);
DAC_EN : OUT std_logic;
DATA_OUT : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
--Inputs
SIGNAL RX_CLK : std_logic := '0';
SIGNAL REQUEST : std_logic := '0';
SIGNAL BUFF_EN : std_logic := '0';
SIGNAL CLK_50MHZ : std_logic := '0';
SIGNAL RX_DATA : std_logic_vector(0 to 3) := (others=>'0');
--Outputs
SIGNAL DAC_EN : std_logic;
SIGNAL DATA_OUT : std_logic_vector(7 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: BUFF PORT MAP(
RX_CLK => RX_CLK,
67
REQUEST => REQUEST,
BUFF_EN => BUFF_EN,
CLK_50MHZ => CLK_50MHZ,
RX_DATA => RX_DATA,
DAC_EN => DAC_EN,
DATA_OUT => DATA_OUT
);
tb1 : PROCESS
BEGIN
RX_CLK <= '0', '1' after 20 ns;
wait for 40 ns;
END PROCESS;
tb2: PROCESS
BEGIN
BUFF_EN <= '1','0' after 640 ns, '0' after 700 ns;
wait for 7520 ns;
END PROCESS;
tb3:PROCESS
BEGIN
REQUEST <= '1', '0' after 31.25 us;
wait for 125 us;
END PROCESS;
tb4: PROCESS
BEGIN
RX_DATA <= "1111", "1111" after 600 ns,
"1111" after 640 ns, "1111" after 680 ns,
"1111" after 720 ns, "1111" after 760 ns,
"1111" after 800 ns, "1111" after 840 ns,
"1111" after 880 ns, "1111" after 920 ns,
"1111" after 960 ns, "1111" after 1000 ns,
"1111" after 1040 ns, "1111" after 1080 ns,
"0000" after 1120 ns, "0000" after 1160 ns,
"0001" after 1200 ns, "0010" after 1240 ns,
"0011" after 1280 ns, "0100" after 1320 ns,
"0101" after 1360 ns, "0110" after 1400 ns,
"0111" after 1440 ns, "1000" after 1480 ns,
"1001" after 1520 ns, "1010" after 1560 ns,
"0001" after 1600 ns, "0000" after 1640 ns,
"0000" after 1680 ns, "0000" after 1720 ns,
"0001" after 1760 ns, "0010" after 1800 ns,
"0011" after 1840 ns, "0100" after 1880 ns,
"0101" after 1920 ns, "0110" after 1960 ns,
"0111" after 2000 ns, "1000" after 2040 ns,
"1001" after 2080 ns, "1010" after 2120 ns,
"1011" after 2160 ns, "1100" after 2200 ns,
"1101" after 2240 ns, "1110" after 2280 ns,
"1111" after 2320 ns, "0000" after 2360 ns,
"0001" after 2400 ns, "0010" after 2440 ns,
"1000" after 2480 ns, "1000" after 2520 ns,
"1111" after 2560 ns, "1111" after 2600 ns,
"1111" after 2640 ns, "1111" after 2680 ns,
"0011" after 2720 ns, "1111" after 2760 ns,
"0111" after 2800 ns, "1010" after 2840 ns,
"1111" after 2880 ns, "1110" after 2920 ns,
"1111" after 2960 ns, "1111" after 3000 ns,
"1111" after 3040 ns, "1111" after 3080 ns,
"1111" after 3120 ns, "1111" after 3160 ns,
"1111" after 3200 ns, "1111" after 3240 ns,
"1111" after 3280 ns, "1111" after 3320 ns,
"0111" after 3360 ns, "1010" after 3400 ns,
"1111" after 3440 ns, "1110" after 3480 ns,
"1111" after 3520 ns, "1111" after 3560 ns,
"1111" after 3600 ns, "1111" after 3640 ns,
"1111" after 3680 ns, "1111" after 3720 ns,
"1111" after 3760 ns, "1111" after 3800 ns,
"1111" after 3840 ns, "1111" after 3880 ns,
"1111" after 3920 ns, "1111" after 3960 ns,
68
"1111" after 4000 ns, "1111" after 4040 ns,
"1111" after 4080 ns, "1111" after 4120 ns,
"1111" after 4160 ns, "1111" after 4200 ns,
"1111" after 4240 ns, "1111" after 4280 ns,
"0000" after 4320 ns, "0000" after 4360 ns,---- VOICE DATA
"0000" after 4400 ns, "0000" after 4440 ns,
"0000" after 4480 ns, "0000" after 4520 ns,
"0000" after 4560 ns, "0000" after 4600 ns,
"0000" after 4640 ns, "0000" after 4680 ns,
"0000" after 4720 ns, "0000" after 4760 ns,
"0000" after 4800 ns, "0000" after 4840 ns,
"0000" after 4880 ns, "0000" after 4920 ns,
"0000" after 4960 ns, "0000" after 5000 ns,
"0000" after 5040 ns, "0000" after 5080 ns,--10
"1111" after 5120 ns, "1111" after 5160 ns,
"1111" after 5200 ns, "1111" after 5240 ns,
"1111" after 5280 ns, "1111" after 5320 ns,
"1111" after 5360 ns, "1111" after 5400 ns,
"1111" after 5440 ns, "1111" after 5480 ns,
"1111" after 5520 ns, "1111" after 5560 ns,
"1111" after 5600 ns, "1111" after 5640 ns,
"1111" after 5680 ns, "1111" after 5720 ns,
"1111" after 5760 ns, "1111" after 5800 ns,
"1111" after 5840 ns, "1111" after 5880 ns,--20
"0000" after 5920 ns, "0000" after 5960 ns,
"0000" after 6000 ns, "0000" after 6040 ns,
"0000" after 6080 ns, "0000" after 6120 ns,
"0000" after 6160 ns, "0000" after 6200 ns,
"0000" after 6240 ns, "0000" after 6280 ns,
"0000" after 6320 ns, "0000" after 6360 ns,
"0000" after 6400 ns, "0000" after 6440 ns,
"0000" after 6480 ns, "0000" after 6520 ns,
"0000" after 6560 ns, "0000" after 6600 ns,
"0000" after 6640 ns, "0000" after 6680 ns,--30
"1111" after 6720 ns, "1111" after 6760 ns,
"1111" after 6800 ns, "1111" after 6840 ns,
"1111" after 6880 ns, "1111" after 6920 ns,
"1111" after 6960 ns, "1111" after 7000 ns,
"1111" after 7040 ns, "1111" after 7080 ns,
"1111" after 7120 ns, "1111" after 7160 ns,
"1111" after 7200 ns, "1111" after 7240 ns,
"1111" after 7280 ns, "1111" after 7320 ns,
"1111" after 7360 ns, "1111" after 7400 ns,
"1111" after 7440 ns, "1111" after 7480 ns;--40
-- "1111" after 7520 ns, "1111" after 7560 ns,
-- "0000" after 7600 ns, "0000" after 7640 ns,
-- "0000" after 7680 ns, "0000" after 7720 ns,
-- "0000" after 7760 ns, "0000" after 7800 ns,
-- "0000" after 7840 ns, "0000" after 7880 ns,
-- "0000" after 7920 ns, "0000" after 7960 ns,
-- "0000" after 8000 ns, "0000" after 8040 ns,
-- "0000" after 8080 ns, "0000" after 8120 ns,--0
-- "1000" after 8160 ns, "0000" after 8200 ns,--1
-- "0100" after 8240 ns, "0000" after 8280 ns,--2
-- "1100" after 8320 ns, "0000" after 8360 ns,--3
-- "0010" after 8400 ns, "0000" after 8440 ns,--4
-- "1010" after 8480 ns, "0000" after 8520 ns,--5
-- "0110" after 8560 ns, "0000" after 8600 ns,--6
-- "1110" after 8640 ns, "0000" after 8680 ns,--7
-- "0001" after 8720 ns, "0000" after 8760 ns,--8
-- "1001" after 8800 ns, "0000" after 8840 ns,--9
-- "0101" after 8880 ns, "0000" after 8920 ns,--10
-- "1101" after 8960 ns, "0000" after 9000 ns,--11
-- "0011" after 9040 ns, "0000" after 9080 ns,--12
-- "1011" after 9120 ns, "0000" after 9160 ns,--13
-- "0111" after 9200 ns, "0000" after 9240 ns,--14
-- "1111" after 9280 ns, "0000" after 9320 ns,--15
-- "0000" after 9360 ns, "1000" after 9400 ns,--16
-- "1000" after 9440 ns, "1000" after 9480 ns,--17
-- "0100" after 9520 ns, "1000" after 9560 ns,--18
69
-- "1100" after 9600 ns, "1000" after 9640 ns,--19
-- "0010" after 9680 ns, "1000" after 9720 ns,--20
-- "1010" after 9760 ns, "1000" after 9800 ns,--21
-- "0110" after 9840 ns, "1000" after 9880 ns,--22
-- "1110" after 9920 ns, "1000" after 9960 ns,--23
-- "0001" after 10000 ns, "1000" after 10040 ns,--24
-- "1001" after 10080 ns, "1000" after 10120 ns,--25
-- "0101" after 10160 ns, "1000" after 10200 ns,--26
-- "1101" after 10240 ns, "1000" after 10280 ns,--27
-- "0011" after 10320 ns, "1000" after 10360 ns,--28
-- "1011" after 10400 ns, "1000" after 10440 ns;--29
wait for 7520 ns;
END PROCESS;
END;
70
B.5 DAC --------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 23:24:02 01/17/2008
-- Design Name: DAC
-- Module Name: D:/docs/acad/ryan/epas/EPAS/SOURCE_CODES/TESTBENCH/DAC_TB.vhd
-- Project Name: EPAS
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: DAC
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY DAC_TB_vhd IS
END DAC_TB_vhd;
ARCHITECTURE behavior OF DAC_TB_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT DAC
PORT(
DAC_EN : IN std_logic;
CLK_50MHZ : IN std_logic;
DATA_IN : IN std_logic_vector(7 downto 0);
SPI_MOSI : OUT std_logic;
SPI_SCK : OUT std_logic;
DAC_CLR : OUT std_logic;
REQUEST : OUT std_logic;
DAC_CS : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL DAC_EN : std_logic := '0';
SIGNAL CLK_50MHZ : std_logic := '0';
SIGNAL DATA_IN : std_logic_vector(7 downto 0) := (others=>'0');
--Outputs
SIGNAL SPI_MOSI : std_logic;
SIGNAL SPI_SCK : std_logic;
SIGNAL DAC_CLR : std_logic;
SIGNAL REQUEST : std_logic;
SIGNAL DAC_CS : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: DAC PORT MAP(
71
DAC_EN => DAC_EN,
CLK_50MHZ => CLK_50MHZ,
DATA_IN => DATA_IN,
SPI_MOSI => SPI_MOSI,
SPI_SCK => SPI_SCK,
DAC_CLR => DAC_CLR,
REQUEST => REQUEST,
DAC_CS => DAC_CS
);
tb1 : PROCESS
BEGIN
DAC_EN <= '0', '1' after 10 ns,'0' after 20 ns;
wait for 200 us;
END PROCESS;
tb2 : PROCESS
BEGIN
CLK_50MHZ <= '1', '0' after 10 ns;
wait for 20 ns;
END PROCESS;
tb3 : PROCESS
BEGIN
DATA_IN <= "00000000", "10000000" after 150 us,
"01000000" after 300 us,
"00100000" after 450 us,
"00010000" after 600 us,
"00001000" after 750 us,
"00000100" after 900 us,
"00000010" after 1050 us,
"00000001" after 1200 us,
"11111111" after 1350 us;
wait for 2000 us;
END PROCESS;
END;
72
Appendix C: CONSTRAINT FILES
C.1: EPAS TOP MODULE
NET "RX_CLK" LOC = "V3";
NET "CLK_50MHZ" LOC = "C9";
NET "RX_DV" LOC = "V2";
NET "RX_DATA<0>" LOC = "V8";
NET "RX_DATA<1>" LOC = "T11";
NET "RX_DATA<2>" LOC = "U11";
NET "RX_DATA<3>" LOC = "V14"; NET "SPI_MOSI" LOC = "T4";
NET "SPI_SCK" LOC = "U16";
NET "DAC_CLR" LOC = "P8";
NET "DAC_CS" LOC = "N8";
73
Appendix D: DELPHI SOURCE CODES
NOTE: WAVEAUDIO UTILITIES IS NEEDED
SENDER MODULE unit Sender;
interface
uses
Windows, Messages, Graphics, Controls, Forms, Dialogs, IdWinsock2, stdctrls,
SysUtils, Classes, IdBaseComponent, IdAntiFreezeBase, IdAntiFreeze,
IdComponent, IdUDPBase, IdUDPClient, IdStack, mmSystem, WaveUtils,
WaveStorage, WaveIO, WaveIn, WaveRecorders, ComCtrls, ToolWin, ActnMan,
ActnCtrls, ImgList, DB, DBClient, MConnect;
type
TUDPMainForm = class(TForm)
SourceGroupBox: TGroupBox;
HostNameLabel: TLabel;
HostAddressLabel: TLabel;
HostName: TLabel;
HostAddress: TLabel;
PortLabel: TLabel;
Port: TLabel;
DestinationLabel: TLabel;
DestinationAddress: TLabel;
UDPClient: TIdUDPClient;
UDPAntiFreeze: TIdAntiFreeze;
Recorder: TLiveAudioRecorder;
GroupBox1: TGroupBox;
pbLevel: TProgressBar;
Start: TButton;
Stop: TButton;
Label1: TLabel;
Label2: TLabel;
cbFormat: TComboBox;
Label3: TLabel;
StatusBar1: TStatusBar;
procedure FormCreate(Sender: TObject);
procedure StartClick(Sender: TObject);
procedure RecorderActivate(Sender: TObject);
procedure RecorderData(Sender: TObject; const Buffer: Pointer;
BufferSize: Cardinal; var FreeIt: Boolean);
procedure RecorderDeactivate(Sender: TObject);
procedure StopClick(Sender: TObject);
procedure RecorderLevel(Sender: TObject; Level: Integer);
procedure cbFormatChange(Sender: TObject);
procedure FormClick(Sender: TObject);
private
{ Private declarations }
procedure BuildAudioFormatList;
public
{ Public declarations }
end;
var
UDPMainForm: TUDPMainForm;
implementation
const
HOSTNAMELENGTH = 80;
RECIEVETIMEOUT = 50; // milliseconds
{$R *.dfm}
procedure TUDPMainForm.FormCreate(Sender: TObject);
begin
Randomize; // remove if you want reproducible results.
HostName.Caption := UDPClient.LocalName;
HostAddress.Caption := GStack.LocalAddress;
Port.Caption := IntToStr(UDPClient.Port);
74
DestinationAddress.Caption := UDPClient.Host;
BuildAudioFormatList;
cbFormat.ItemIndex:=Ord(Recorder.PCMFormat)-1;
UDPClient.ReceiveTimeout := RECIEVETIMEOUT;
Label3.Caption:= DateTimeToStr(Now);
end;
procedure TUDPMainForm.StartClick(Sender: TObject);
begin
Recorder.PCMFormat := TPCMFormat(cbFormat.ItemIndex + 1);
Recorder.Active:= True;
StatusBar1.SimpleText:=' Sending voice announcement...';
Label3.Caption:= 'An announcement is made on '+ DateTimeToStr(Now);
end;
procedure TUDPMainForm.RecorderActivate(Sender: TObject);
begin
Stop.Visible:=True;
Start.Visible:=False;
cbFormat.Enabled:=False;
end;
procedure TUDPMainForm.RecorderData(Sender: TObject; const Buffer: Pointer;
BufferSize: Cardinal; var FreeIt: Boolean);
var
WaveFormat: TWaveFormatEx;
WaveFormatSize: Integer;
begin
try
SetPCMAudioFormatS(@WaveFormat, Recorder.PCMFormat);
WaveFormatSize := SizeOf(WaveFormat);
UDPClient.SendBuffer(WaveFormatSize, SizeOf(WaveFormatSize));
UDPClient.SendBuffer(WaveFormat, WaveFormatSize);
UDPClient.SendBuffer('255.255.255.255',3435,Buffer^,BufferSize);
finally
FreeIt:=True;
end;
end;
procedure TUDPMainForm.RecorderDeactivate(Sender: TObject);
begin
Start.Visible:=True;
Stop.Visible:=False;
cbFormat.Enabled:=True;
end;
procedure TUDPMainForm.StopClick(Sender: TObject);
begin
Recorder.Active:= False;
StatusBar1.SimpleText:=' Ready for an announcement... ';
end;
procedure TUDPMainForm.RecorderLevel(Sender: TObject; Level: Integer);
begin
pbLevel.Position := Level;
end;
procedure TUDPMainForm.BuildAudioFormatList;
var
pcm:TPCMFormat;
WaveFormat:TWaveFormatEx;
begin
with cbFormat.Items do
begin
BeginUpdate;
try
Clear;
for pcm:=Succ(Low(TPCMFormat)) to High(TPCMFormat) do
begin
SetPCMAudioFormatS(@WaveFormat, pcm);
Add(GetWaveAudioFormat(@WaveFormat));
end;
finally
EndUpdate;
end;
end;
end;
75
procedure TUDPMainForm.cbFormatChange(Sender: TObject);
begin
StatusBar1.SimpleText:=' Updating Sampling rate...';
end;
procedure TUDPMainForm.FormClick(Sender: TObject);
begin
MessageDlg (' Ethernet Based Public Address System Using FPGA//Team members:Jamela,Ryan and Junriy//Advisers:Karla Madrid
and Sihawi Khalid',
mtInformation, [mbok],0);
end;
end.
View publication statsView publication stats