ECE 477 Final Report Spring 2009Team 6 ALF
Team Members:
#1: Andrew Hartnett Signature: ____________________ Date: _________
#2: David Eslinger Signature: ____________________ Date: _________
#3: Curt Schieler Signature: ____________________ Date: _________
#4: Ken Pesyna Signature: ____________________ Date: _________
CRITERION SCORE MPY PTSTechnical content 0 1 2 3 4 5 6 7 8 9 10 3Design documentation 0 1 2 3 4 5 6 7 8 9 10 3Technical writing style 0 1 2 3 4 5 6 7 8 9 10 2Contributions 0 1 2 3 4 5 6 7 8 9 10 1Editing 0 1 2 3 4 5 6 7 8 9 10 1Comments: TOTAL
ECE 477 Final Report Spring 2009
TABLE OF CONTENTS
Abstract 1
1.0 Project Overview and Block Diagram 1
2.0 Team Success Criteria and Fulfillment 3
3.0 Constraint Analysis and Component Selection 4
4.0 Patent Liability Analysis 9
5.0 Reliability and Safety Analysis 17
6.0 Ethical and Environmental Impact Analysis 21
7.0 Packaging Design Considerations 25
8.0 Schematic Design Considerations 28
9.0 PCB Layout Design Considerations 31
10.0 Software Design Considerations 34
11.0 Version 2 Changes 42
12.0 Summary and Conclusions 43
13.0 References 44
Appendix A: Individual Contributions A-1
Appendix B: Packaging B-1
Appendix C: Schematic C-1
Appendix D: PCB Layout Top and Bottom Copper D-1
Appendix E: Parts List Spreadsheet E-1
Appendix F: Software Listing F-1
Appendix G: FMECA Worksheet G-1
-ii-
ECE 477 Final Report Spring 2009
Abstract
This report is a complete presentation of the design of ALF. The report contains the analysis,
constraints, and considerations developed throughout the design process, as well as the final
design. The final design includes the documentation for the hardware, software, and packaging.
1.0 Project Overview and Block Diagram
ALF is a device that can record and store audio to memory, playback audio from memory, and
manipulate audio while streaming. The audio manipulation that ALF is capable of is to add a
flange effect. The original intent of ALF was also to implement the FLAC audio compression
algorithm, specifically rice coding, while storing audio to memory and also implement FLAC
audio decompression during audio playback. However due to the complexity of the FLAC
algorithm, implementing FLAC was not reasonably achievable in the time available. ALF has a
line-in jack to accept analog audio input for recording and streaming. In addition, there will be a
line-out jack to connect audio output to headphones or speakers for playback and streaming.
ALF can store up to 20 seconds of audio data in the onboard memory. ALF has an intuitive user
interface in the form of 3 pushbuttons and an LCD that allows the user to control the record,
stream, playback, volume, storage, and manipulation modes. The user will be presented with a
menu for each of these modes and can select between different options within each menu and
cycle through the menus using the pushbuttons. The block diagram and final picture of the
project are shown below.
-1-
ECE 477 Final Report Spring 2009
2.0 Team Success Criteria and Fulfillment
Revised Project Specific Success Criteria An ability to store data in external memory.
An ability to display relevant information on an LCD.
An ability to send commands from a microcontroller to an FPGA.
An ability to capture audio from a CODEC.
An ability to manipulate audio (i.e. produce an effect or filter) while streaming audio.
Old Project Specific Success Criteria An ability to encode streaming audio into a FLAC format using the Rice compression
algorithm.
An ability to decode FLAC for playback.
An ability to store data in external memory
An ability to compute latency between input audio and playback.
An ability to display relevant information on an LCD.
All of the revised Project Specific Success Criteria were fulfilled. Three of the old Project
Specific Success Criteria were not achieved.
-3-
ECE 477 Final Report Spring 2009
3.0 Constraint Analysis and Component Selection
3.1 Introduction
This project will be able to receive an analog audio input, compress it into a FLAC file, and
then decompress the FLAC file for audio playback. The FPGA will do the linear predictive
coding and rice coding computations. The design will be powered from a wall outlet, implying
loose power constraints. The device should also be able to store at least one minute of
compressed audio data. Finally, the user needs an intuitive interface that will control the audio
recorder and cycle through the information displayed on the LCD.
3.2 Design Constraint Analysis
One constraint that will guide the selection of the parts is the objective of achieving CD
quality audio, a well-justified objective when dealing with lossless compression. Another major
constraint is the computational requirement of the FLAC coding, which will be done solely in the
FPGA, for two reasons. First, the computations can be done quickly in the FPGA and second,
the purpose of this project lies in implementing Rice coding in an FPGA. The microcontroller
will be using an SPI interface to connect to the LCD. Four pushbuttons will also be connected to
general purpose I/O pins of the microcontroller for user interface. The microcontroller should
also have a UART so that the data on SRAM can be dumped for debugging. In order to get about
30 seconds of audio at an estimated compression ratio of 60%, a 4 MB SDRAM chip is required:
When ALF is compressing audio, we will collect 4096 samples of audio to have one
‘block’ of audio which will then be compressed. ALF will compress one block of audio while we
are collecting samples for the next block of audio. It will take
To collect enough samples for one block of audio, meaning that we have 8,533,000 clock cycles
to do all the computations for compression as well. This should be an ample amount of time to
-4-
ECE 477 Final Report Spring 2009
perform compression. There are very few constraints for the microcontroller; it needs to be able
to refresh the LCD fast enough via UART, and communicate with the FPGA via SPI.
3.3 Computation Requirements
In order to achieve CD quality audio, the incoming audio will need to be sampled at a rate of
at least 48 kHz. All computations for FLAC encoding will need to be done fast enough to keep
up with the sampling rate if ALF is to be able to compress a “live” stream of audio. Also, the
FLAC data needs to be decoded fast enough for continuous playback. For each sample in a
frame, the design is going to compute the autocorrelation between the previous samples and the
current sample. Based on the autocorrelation of the frame, it will assign a predictor from a set of
fixed predictors. The design will then compute the residual between the predicted value and the
original data. The residual is then encoded in one pass using the Rice coding algorithm. Because
the Rice coding is a simpler algorithm than the linear predictive coding, the latter will likely be
the bottleneck of the design. One feature of the design will be the capability to calculate latency
from encoding to decoding, which can be done in either the FPGA or the microcontroller. This
computation is fairly straightforward, and will not create a system bottleneck. The latency
displayed will either be a running average, a windowed average, or the current latency.
3.4 Interface Requirements
An Audio CODEC chip will be used to sample the audio and play back the uncompressed
data, using an internal ADC and DAC. There are 8 pins that will be needed for this chip to
communicate with and transfer data to and from the FPGA. Also, there will need to be 38 pins
for connecting the FPGA and SDRAM: a 16 bit data bus, a 12 bit address bus, and 10 additional
pins for configuration. An SPI interface will be used to connect the microcontroller to the LCD.
Four pushbuttons will be used to allow a user to start and stop recording, play back stored data,
cycle through the information being displayed on the LCD, and select whether the recorded data
will be saved to external memory or immediately played back to determine latency. The
microcontroller has a maximum of 25 mA that it can sink or source on any given I/O pin with a
total of 200 mA that it can sink or source across all pins. The microcontroller interfaces with the
LCD using SPI and pushbuttons through general purpose I/O. However, the digital VOH for the
microcontroller is Vdd (nominal 2.5V) and the LCD runs on 5V. Therefore, a DC voltage
-5-
ECE 477 Final Report Spring 2009
controller will be needed to allow for proper SPI communication between these two devices. The
FPGA has a minimum DC output current per pin of -25mA and a maximum of 40mA.
3.5 On-Chip Peripheral Requirements
The microcontroller of this design will need two SPI modules and a UART module. One SPI
module will be used for interfacing with the LCD while the other SPI module will likely be used
to communicate with the FPGA. The UART will be used to dump the data received from the
external memory chip onto a computer for debugging.
3.6 Off-Chip Peripheral Requirements
One possible method to achieve CD quality audio is for the design to have a 1 channel 16 bit
parallel ADC (and matching DAC). However, the design will instead use an Audio CODEC that
has these things built in. This Audio CODEC should have headphone drivers and a
programmable sample rate and resolution. The incoming audio data will then be passed from the
CODEC to the FPGA. After compression, the data will be stored on off-chip, on-board SDRAM.
The uncompressed audio will then be passed back to the CODEC for playback over the line-out
jack.
3.7 Power Constraints
The PIC [1] microcontroller has an input voltage requirement of 2.2 - 3.6V. The Cyclone III
FPGA [2] has input voltage requirement of 1.2V for the core logic. The SDRAM [3] has an input
voltage requirement of 3.3V and operates at a maximum supply current of 145 mA. The
audio CODEC [4] has an input voltage requirement 3.3V. The LCD [5] has an input voltage
requirement of 5V and operates at 380 mA with the backlight on and 9mA with the backlight off.
ALF will have 3 LDOs; a 9V to 5V regulator, a 5V to 1.2V regulator, and a 5V to 3.3V/2.5V
regulator. Since we are using a 4 layer board, each of these voltages will go to its own section of
the power plane.
3.8 Packaging Constraints
This design is not constrained by size or weight. Within reason, the package should be
portable and not sensitive to small movements. There should be easy access to a port for the
-6-
ECE 477 Final Report Spring 2009
analog input and output (microphone, speaker, etc). The final project fits in a 6.3” by 6.3” by
2.4” project box, with the PCB being approximately 5.25” by 5.25”.
3.9 Cost Constraints
As this design is not directly competing with any existing projects (it is a research project),
low-cost is a benefit but not a constraint. Cost for the final project may be high because this is a
high-quality audio recorder. This design will be sponsored up to an amount of $1000; however
this amount should be more than required.
3.10 Component Selection Rationale
Table 3.1: Major Component SelectionComponent needed Possible parts Part Chosen
FPGA Xilinx Spartan 3a, Altera
Cyclone III
Altera Cyclone III
Microcontroller PIC24F, Atmel AT89 PIC24F
Memory SDRAM, SRAM SDRAM (specific part
that is on development
board)
Audio Sampling CODEC, our own circuit CODEC (specific part
that is on development
board)
The Altera Cyclone III and the Xilinx Spartan 3a are two FPGAs that fit the needs of this
project. The Spartan 3a costs less, but more support and resources are available for the Cyclone
III. Consequently, the Cyclone III will be used for this project. The Microchip PIC24F and the
Atmel AT89 are both microcontrollers that fit the needs of this project. The PIC24F is a 16-bit
microcontroller that operates at 32 MHz with 64 kB of FLASH. The AT89 is an 8-bit
microcontroller that operates at 20 MHz with 4 kB of FLASH. Both of the microcontrollers
have SPI and UART modules; however, the AT89 only has one SPI module while the PIC24F
has two. The AT89 could overcome this by being the master for two slave devices. The benefit
-7-
ECE 477 Final Report Spring 2009
of the AT89 is that it is smaller, which agrees with the low microcontroller resources required
by the project. However, the PIC24F will be chosen because of familiarity with the product, the
fact that it has two SPI modules, and the flexibility of the microcontroller to handle unforeseen
tasks. SDRAM, SRAM, and FLASH are all available types of memory that could be used to
store compressed data. However, it is easier to obtain large SDRAM than SRAM.FLASH will
not be used because data will have to be written to memory frequently. This leaves SDRAM as
the obvious choice for the design. In order to facilitate immediate prototyping, the IS42S16400
SDRAM chip, the same as on the development board, will be used. Two systems could be used
for the analog audio input/output. One system entails purchasing a16 bit ADC and DAC, and
using a preamp and post-DAC filter. The other option simply uses an Audio Codec with these
features built-in. The Audio CODEC is a very low-cost system, and easily integrates into the
design. The Audio CODEC will be used because using a separate ADC and DAC only adds
unnecessary complexity. In order to facilitate immediate prototyping, the proposed Audio
CODEC, WM8731SEDS, will be the same as on the development board.
3.11 Summary
This project’s main design constraints are strongly determined by two primary objectives:
achieving high-quality audio and performing FLAC-related computations faster than the audio
sampling rate. Other design constraints arise from the need to store large amounts of data, and
the need for user control and display. Given these constraints, the FPGA will act as the core,
performing the FLAC computations, while the Audio CODEC will handle the audio input and
output. SDRAM will be the external memory used for storing data, and a microcontroller will
provide the SPI and UART necessary for interfacing between the FPGA and user (LCD and
pushbuttons). Because of the nature of the project, the cost, power, and packaging constraints
are largely minor. The component selection was mainly guided by familiarity and availability of
products. In the end, the Altera FPGA was chosen because of the local development board,
and the Audio CODEC was chosen because it merged audio input and output into a simple
environment. As for the other major components, the SDRAM was chosen because of size
requirements, and the PIC because of familiarity.
-8-
ECE 477 Final Report Spring 2009
4.0 Patent Liability Analysis
4.1 Introduction
ALF allows a user to record audio using lossless compression from a line-in and either store
the compressed file for later playback, or decode immediately to calculate the latency of the
compression algorithm. The audio will be compressed into the Free Lossless Audio CODEC
(FLAC) format, so that performance of the Rice Encoding method can be analyzed when
performed on an FPGA. The audio input and output will consist of line in and line out jacks, and
an Audio CODEC chip that handles analog and digital conversion. ALF will be able to store at
least one minute of compressed audio, which will be stored in SDRAM; there will also be an
RS232 connection for dumping the memory for external viewing. The FPGA performs all of the
actual compression, decoding, and interfacing with the SDRAM and the left and right audio
channels via an Audio CODEC. The user will have four pushbuttons that are accessible, one to
begin/stop recording, one to play audio currently saved in internal memory, one to change what
is currently displayed on the LCD, and one to select either to save the audio into internal memory
or immediately decode the audio. There will be a small LCD to display to the user information of
interest about the audio, such as latency, size of file saved, and duration of recorded audio. All
requests by the user will be initially handled by the microcontroller, which will then pass any
necessary information to the Field Programmable Gate Array (FPGA). ALF could certainly be
susceptible to patent infringement since audio compression is by no means a new concept, and
has been implemented in many devices currently patented and on the market. Whether ALF's
goal of implementing FLAC (and Rice coding) in an FPGA has been patented is the purpose of
this liability analysis.
4.2 Results of Patent and Product Search
After an extensive patent search, three patents have been identified which ALF is most
likely to infringe upon. The first patent [11], titled "Rice Lossless Compression Module," filed
by Honeywell International, is a patent for implementing a Rice coding compression module in
an FPGA. The second patent [12], titled "Lossless compression/decompression of digital audio
data," filed by Merging Technologies, is a patent for a method of compression and
decompressing audio losslessly using waveform prediction methods and Huffman coding tables.
The third patent [13], titled "Lossless compression method and apparatus for data storage and
-9-
ECE 477 Final Report Spring 2009
transmission," is a patent for compressing data and storing it to a storage device as well as
decompressing it and sending it to an external device. Below are abstracts provided by each
patent as well as relevant claims that ALF may infringe upon.
4.2.1
United States Patent #7430328
Title: Rice lossless compression module
Filing Date: 12/01/2004
Assignee: Honeywell International Inc.
Abstract:
A Rice coding data compression module includes a memory interface operable to receive sensor
data from memory, a data normalization module operable to normalize received sensor data, an
encoder operable to apply a Rice compression algorithm to the normalized data to produce
compressed sensor data, a data management module operable to apply packet formatting to the
compressed sensor data to produce formatted compressed sensor data packets; and a memory
interface operable to store the formatted compressed sensor data packets to memory.
Key claims of potential infringement:
1. A Rice coding data compression module, comprising: a memory interface operable to receive
sensor data from memory; a data normalization module operable to normalize received sensor
data; an encoder operable to apply a Rice compression algorithm to the normalized data to
produce compressed sensor data; a data management module operable to apply packet formatting
to the compressed sensor data to produce formatted compressed sensor data packets; and a
memory interface operable to store the formatted compressed sensor data packets to memory.
2. The Rice coding data compression module of claim 1, wherein the module is embodied in a
FPGA (Field Programmable Gate Array).
4.2.2
United States Patent #5884269
-10-
ECE 477 Final Report Spring 2009
Title: Lossless compression/decompression of digital audio data
Filing Date: 12/01/2004
Assignee: Merging Technologies (Puidoux, CH)
Abstract:
An audio signal compression and decompression method and apparatus that provide lossless,
real-time performance. The compression/decompression method and apparatus are based on an
entropy encoding technique using multiple Huffman code tables. Uncompressed audio data
samples are first processed by a prediction filter which generates prediction error samples. An
optimum coding table is then selected from a number of different preselected tables which have
been tailored to different probability density functions of the prediction error. For each frame of
prediction error samples, an entropy encoder selects the one Huffman code table which will yield
the shortest encoded representation of the frame of prediction error samples. The frame of
prediction error samples is then encoded using the selected Huffman code table. A block
structure for the compressed data and a decoder for reconstructing the original audio signal from
the compressed data are also disclosed.
Key claims of potential infringement:
1. A method of encoding audio data comprising the steps of:
--generating a frame of prediction error samples from a frame of audio data samples;
--determining the cost of coding the frame of prediction error samples using each of a plurality of
code tables, said plurality of code tables each corresponding to a different probability density
function of a distribution of the prediction error samples;
--determining which one of the plurality of code tables will provide the lowest cost of coding the
frame of prediction error samples; and
--coding the frame of prediction error samples using the one of the plurality of code tables
providing the lowest cost of coding the frame of prediction error samples.
2. The method of claim 1, wherein the cost of coding the frame of prediction error samples
includes the number of bits used to represent the encoded frame of prediction error samples.
-11-
ECE 477 Final Report Spring 2009
3. The method of claim 1, further comprising the step of forming a block of encoded audio data
by adding a header to the frame of encoded prediction error samples.
4. The method of claim 3 further comprising the step of forming an index file, the index file
including block length and level information for each of a plurality of blocks of encoded audio
data.
4.2.3
United States Patent Application #20060010151 (Patent pending)
Title: Lossless compression method and apparatus for data storage and transmission
Filing Date: 05/25/200
Author: Star Sung, Chih-ta (Glonn, DE)
Abstract:
The present invention provides method and apparatus of a lossless data compression to reduce
the amount of data to be transmitted or to be saved into a storage device. In the VLSI
implementation, a data path module combined with some state machines support multiple
formats of data file and to execute the function of the lossless data compression. The amount of
the program data of a File System is reduced by a lossless compression method before it is saved
into the storage device and to be recovered to execute the function of a File System. Before
transmission, the data file compressed by the lossless compression algorithm coupled with the
corresponding decompression code will be packed into a data stream and the receiving node will
recover the data file by executing the decompression code.
Key claims of potential infringement:
1. A method of performing lossless data compression and decompression for data storage,
comprising: reading a target data file from an external device; compressing the target data file by
a corresponding lossless compression algorithm according to different file formats into
compressed data; storing the compressed data into a storage device; reading a compressed target
data file from a location of a storage memory; decompressing a target data file by a
-12-
ECE 477 Final Report Spring 2009
corresponding decompression algorithm according to different file formats; and sending the
decompressed data into the external device;
...
3. The method of claim 1, wherein a micro-controller engine is implemented to control the data
flowing between an external device, a semiconductor memory and a lossless compression and
decompression engine.
...
5. The method of claim 1, wherein a storage memory is an SRAM or a DRAM.
4.3 Analysis of Patent Liability
It can be concluded that ALF has literal infringement with one patent, identified above, and
also possible infringement under the doctrine of equivalents with the other two patents identified.
Under the first patent, titled "Rice Lossless Compression Module," the claims state that there
is a Rice compression module implemented in an FPGA. It can be determined that ALF has
literal infringement with this patent. Though ALF actually implements the FLAC compression
algorithm, FLAC uses Rice coding to code the residuals of the difference between the actual
input audio waveform and the waveform prediction. Thus ALF's added function of using FLAC
does not eliminate the infringement upon this patent. Since ALF is performing exactly the same
function, lossless audio compression, in exactly the same way, using Rice coding in an FPGA, it
can be concluded that ALF has literal infringement with this patent.
Under the second patent, titled "Lossless compression/decompression of digital audio data,"
claim 1 states that a frame of prediction error samples is generated from a frame of audio data
samples. These prediction error samples are then coded using one of a set of Huffman Code
tables. Within the FLAC algorithm that ALF will use, prediction error samples will be created
from the audio input samples. Therefore ALF will infringe upon this part of the claim. However,
ALF will then encode these error samples, called residuals, using Rice coding and not code
tables. Thus, ALF does not infringe upon this part of the claim. ALF also infringes upon claims
2, 3, and 4. For ALF, the cost of encoding the residuals is the number of bits used to represent
the encoded frame of residuals. In addition, each frame will contain a header to form a block of
encoded data and there will also be an overarching index file which will contain critical
information about the FLAC file such a block length. After analyzing these claims, it could be
-13-
ECE 477 Final Report Spring 2009
concluded that ALF performs substantially the same function in substantially the same way as
this patent. If so, ALF would infringe upon this patent under the doctrine of equivalents. It could
also be debated, however, that since FLAC is a "Free Lossless Audio Codec" and is open-source,
it is not patentable and does not infringe upon the software algorithms mentioned in the claims
above. In the FLAC license, its developers mention that "Neither the FLAC nor Ogg FLAC
formats nor any of the implemented encoding/decoding methods are covered by any known
patent." Thus, one could argue that ALF is not actually infringing on this patent.
Under the third patent, titled "Lossless compression method and apparatus for data storage
and transmission," claim 1 states that the data compression is done by reading the data from an
external device, compressing it according to a file format (such as FLAC), and storing the
compressed data to a storage device. It also states that decompression is done in the opposite
manner by reading the data file from storage memory, decompressing it according to a file
format and sending the decompressed data to an external device. In ALF, data will be retrieved
by sampling it from streaming audio input. Therefore, ALF does not infringe upon this part of
the claim. However, ALF will compress the data according to the file format FLAC, and will
then have the option to store this compressed data to SDRAM. Thus, ALF may infringe upon this
part of the claim. Claim 3 of the patent states that a microcontroller is used to control data flow
between the external device, the memory, and the compression and decompression engine. ALF's
microcontroller will not control the data flow between the input data, our FPGA, and the
memory. Conversely, our microcontroller is merely used to signal the FPGA when to begin
sampling, compressing/decompressing, and storing data. Thus ALF does not infringe upon this
claim. Claim 5 states that the storage memory is SRAM or DRAM. ALF uses SDRAM which is
a synchronous from of DRAM. Though it may sound similar to DRAM, SDRAM is actually
functions quite differently than DRAM which is asynchronous. Therefore, ALF most likely
would not infringe on this claim. After analyzing these claims, it is unclear as to whether ALF
would infringe upon this patent. On one hand, it could be concluded that ALF performs
substantially the same function in substantially the same way as this patent. If so, ALF would
infringe upon this patent under the doctrine of equivalents. However, it could also be concluded,
based upon the claims mentioned above, that ALF is performing a slightly different function in a
slightly different way since ALF is sampling streaming in input (instead of reading a data file
from storage) and is using an FPGA instead of a microcontroller to control data flow.
-14-
ECE 477 Final Report Spring 2009
4.4 Action Recommended
For the Honeywell patent, the literal infringement forms the basis for our entire project:
implementing rice coding in an FPGA. Thus, there is fundamentally no way to work around this
patent. As a result, if ALF was commercialized, it would be practical to buy a license for this
patent or pay royalties to the inventor for each device created.
With respect to the Merging Technologies patent, ALF may be able to get around this patent
by mentioning that FLAC is a "Free Lossless Audio Codec" and is open source software.
Therefore, from a purely software viewpoint, FLAC itself is not patentable. Though many of the
algorithms in FLAC seem to match up with the algorithms in this patent, FLAC, as open-source
software, may not actually be infringing on them. Thus, one could argue that ALF is not actually
infringing on this patent.
With respect to the Star Sung patent, the only part of the patent that ALF could be infringing
upon is the compression and storage claims. Since the main purpose of the patent is to store
compressed data to a storage device and decompress data from this device, ALF could easily
avoid infringing upon this patent by eliminating storing the compressed data at all. ALF could, if
necessary, merely compress the data and immediately decompress it and still achieve its purpose
of implementing Rice Coding in and FPGA. However, as mentioned earlier, it could be
concluded that ALF performs a different enough function in a different enough way to not
infringe upon this patent in the first place.
4.5 Summary
There are three primary patents which ALF has potential to infringe upon. The first patent
titled "Rice lossless compression module" filed by Honeywell International patents
implementing a Rice Coding module in an FPGA. Since this is the primary purpose of ALF,
ALF has literal infringement with this patent. The second patent titled "Lossless
compression/decompression of digital audio data" filed by a company called Merging
Technologies patents a method of compressing and decompressing an audio signal to provide
lossless, real-time performance using waveform prediction methods and Huffman coding tables.
ALF may be able to get around this patent by claiming that the FLAC codec is open source, and
therefore, from a software standpoint, even though it uses similar compression methods, does not
infringe upon this patent. The third patent titled "Lossless compression method and apparatus for
data storage and transmission," filed by Star Sung is a patent for compressing data and storing it
-15-
ECE 477 Final Report Spring 2009
to a storage device as well as decompressing it and sending it to an external device. From a high-
level viewpoint, it appears that ALF may be infringing upon this patent since it performs a
similar function. However, looking more closely at the individual claims, it can be determined
that there are a number of claims that show that ALF implements this function in a slightly
different way. In conclusion, when looking at these patents altogether, it is likely that one would
most likely need to buy licenses or pay royalties to inventors in order to commercialize ALF as
is.
-16-
ECE 477 Final Report Spring 2009
5.0 Reliability and Safety Analysis 5.1 Introduction
ALF allows a user to record audio using lossless compression from a line-in and either store
the compressed file for later playback, or decode immediately to calculate the latency of the
compression algorithm. The audio will be compressed into the Free Lossless Audio CODEC
(FLAC) format, so that performance of the Rice Encoding method can be analyzed when
performed on an FPGA. The audio input and output will consist of line-in and line-out jacks, and
an Audio CODEC chip that handles analog and digital conversion. ALF will be able to store at
least thirty seconds of compressed audio, which will be stored in SDRAM; there will also be an
RS232 connection for dumping the memory for external viewing. The FPGA performs all of the
actual compression, decoding, and interfacing with the SDRAM and the left and right audio
channels via an Audio CODEC. The user will have three pushbuttons, one to begin/stop
recording, one to play audio currently saved in internal memory, one to change what is currently
displayed on the LCD, and one to select either to save the audio into internal memory or
immediately decode the audio. There will be a small LCD to display to the user information of
interest about the audio, such as latency, size of file saved, and duration of recorded audio. All
requests by the user will be initially handled by the microcontroller, which will then pass any
necessary information to the Field Programmable Gate Array (FPGA). In this report, the
reliability and safety of ALF is analyzed. In order to identify the possible failures that could
occur, the schematic for ALF was broken into several functional blocks to analyze separately.
The most critical safety issue concerning ALF is the possibility of a fire resulting from a short in
a power regulator. A few of the most critical components that will be analyzed for reliability are
the Microchip PIC24FJ64 microcontroller [1], the Altera EP3C40 FPGA [2], and the Diodes Inc.
AP1117 five volt linear regulator [14].
5.2 Reliability Analysis
The three components most likely to fail in the design are the FPGA, the PIC micro-
controller, and the five volt regulator. These components were chosen due to their complexity,
criticality to the product functioning, and power dissipation.
The following tables show the parameters used for each component to calculate the number
of failures per 106 hours and mean time to failure (MTTF). All three of these components use
-17-
ECE 477 Final Report Spring 2009
the following model from page 25 of the Military Handbook – Reliability Prediction of
Electronic Equipment [15]: and .
Table 5.1: FPGA (Altera EP3C40)Parameter Value Assumptions
C1 0.29MOS Digital and Linear Gate/Logic Array, 30,001 to 60,000 Gates
πT 2.8 Linear, temp of 70°CC2 0.0748 140 Functional Pins, NonhermeticπE 2 Ground FixedπQ 10 Commercially manufactured componentπL 1 More than 2 years in productionλP 9.616 Failures/106 hours
MTTF 103,993.3444 hours = 11.871 years
Table 5.2: Microcontroller (Microchip PIC24FJ64)Parameter Value Assumptions
C1 0.28 16 bit, CMOSπT 2.8 Linear, temp of 70°CC2 0.01 22 Functional Pins, NonhermeticπE 2 Ground FixedπQ 10 Commercially manufactured componentπL 1 More than 2 years in productionλP 8.04 Failures/106 hours
MTTF 124,378.1095 hours = 14.198 years
Table 5.3: 5V Linear Regulator (Diodes Inc AP1117)Parameter Value Assumptions
C1 0.01 Linear, MOS device, between 1-100 transistorsπT 2.8 Linear, max temp of 70°CC2 0.0012 3 Functional Pins, NonhermeticπE 2 Ground FixedπQ 10 Commercially manufactured componentπL 1 More than 2 years in productionλP 0.304 Failures/106 hours
MTTF 3,289,473.684 hours = 375.511 years
These results are lower than they should be for recommended reliability. The MTTF for the
five volt regulator (Table 3) is especially low for its criticality rating (high). The πT used in
these calculations contributed to the low results. If a more realistic value (temperature of 50°C)
was used, the MTTFs would increase to more reasonable values.
-18-
ECE 477 Final Report Spring 2009
5.3 Failure Mode, Effects, and Criticality Analysis (FMECA)
There are three criticality levels for types of failures in the output of this design. A “High”
failure is one that could result in injury to the user. The only “High” failures for this product are
related to the power supply, and refer to the rare possibility that a short in one of the regulators
causes a fire. An acceptable failure rate for a “High” failure is 10-9 because of potential
injury to the user. A “Medium” failure is a failure that could result in major damage to the
many components (or a single component that would be difficult to replace) of the product, but
not cause any injury to the user. An example of a “Medium” failure is the SDRAM getting fried
because the SDRAM chip has 54 pins and would be difficult to replace. An acceptable failure
rate for a “Medium” failure is 10-7. The third criticality level is a “Low” failure. This
type of failure results in minimal damage to the product and is easily fixed. The pushbutton
wires becoming unconnected is an example of a “Low” failure because no real damage is
caused. The wires can be easily reconnected to solve the problem. An acceptable failure rate
for a “Low” failure is < 10-6.
The schematic for ALF has been broken into four functional blocks: Power Supply, Audio
Circuitry, FPGA Circuitry, and Microcontroller circuitry. These blocks can be found in
Appendix A. Appendix B contains an FEMCA Worksheet that shows the different failure
modes possible for each functional block. It also shows possible causes, effects, and criticality
level of each failure mode.
There are two circuit design changes that would dramatically increase the overall safety of
the device. First, the addition of a fuse between the input power jack to the power switch to
protect from excessive and possibly dangerous current draw. Second, diode circuitry could be
introduced before the 5V regulator that would protect the board from input power with reversed
polarity.
5.4 Summary
This report has shown the reliability and safety analysis done on ALF’s design. Overall,
ALF is very reliable. However, the lifetime of the components could be increased by ensuring
that the temperature coefficient, T, is as low as possible. ALF is also a very safe design with
-19-
ECE 477 Final Report Spring 2009
only a few high criticality failures possible. Additional safety measures, the fuse and diode
circuitry, would significantly reduce the possibility of these high criticality failures.
-20-
ECE 477 Final Report Spring 2009
6.0 Ethical and Environmental Impact Analysis
6.1 Introduction
ALF allows a user to record audio using lossless compression from a line-in and either store
the compressed file for later playback, or decode immediately to calculate the latency of the
compression algorithm. The audio will be compressed into the Free Lossless Audio CODEC
(FLAC) format, so that performance of the Rice Encoding method can be analyzed when
performed on an FPGA. The audio input and output will consist of line in and line out jacks, and
an Audio CODEC chip that handles analog and digital conversion. ALF will be able to store at
least one minute of compressed audio, which will be stored in SDRAM; there will also be an
RS232 connection for dumping the memory for external viewing. The FPGA performs all of the
actual compression, decoding, and interfacing with the SDRAM and the left and right audio
channels via an Audio CODEC. The user will have four pushbuttons that are accessible, one to
begin/stop recording, one to play audio currently saved in internal memory, one to change what
is currently displayed on the LCD, and one to select either to save the audio into internal memory
or immediately decode the audio. There will be a small LCD to display to the user information of
interest about the audio, such as latency, size of file saved, and duration of recorded audio. All
requests by the user will be initially handled by the microcontroller, which will then pass any
necessary information to the Field Programmable Gate Array (FPGA). In this report, the ethical
and environmental impacts are analyzed. The main ethical considerations for ALF involve
proper credit for source code and safety concerns. ALF's environmental impact will be mostly
centered around the manufacturing of the PCB, and the disposal of the PCB and LCD. In both
the ethical and environmental analysis, the IEEE Code of Ethics [16] will act as a guide and
framework.
6.2 Ethical Impact Analysis
A general structure for ethical considerations is laid out nicely in the IEEE Code of Ethics.
Although each of the ten directives of the code would apply to the design and marketing process,
numbers 3, 7, and 9 are most relevant to ALF.
Number three in the code is an agreement “to be honest and realistic in stating claims or
estimates based on available data”. ALF will be capable of compressing audio according to the
-21-
ECE 477 Final Report Spring 2009
FLAC format and Rice compression, but it might be tempting to purport to achieve faster
compression while secretly compromising the FLAC format. For example, one could arguably
follow the “FLAC format” by simply making each audio frame “verbatim”, thus achieving
instant encoding (but with zero compression). However, this claim would be unethical. There is
an ethical obligation to be honest and realistic about the features of a device, and ALF would
meet this obligation by providing a comprehensive user manual.
Number seven in the Code of Ethics instructs the member to “seek, accept, and offer honest
criticism of technical work, to acknowledge and correct errors, and to credit properly the
contributions of others”. This ethical consideration tugs at the essence of ALF, because ALF is
built on used code, both in its peripheral interfacing and in its FLAC encoding/decoding
algorithm. FLAC source code and much of the VHDL code is under the GNU General Public
License (GPL) [17], and the challenge in bringing the design to market would be to follow all of
the conditions of the license. Some of terms and conditions include passing on the same
freedoms that were received, such as making source code available and not allowing patents to
restrict development of the software, and also including the GNU GPL terms. ALF would need
to include an online link to the source code that was modified under the GPL license.
Number nine concerns safety: “to avoid injuring others, their property, reputation, or
employment by false or malicious action”. During ALF's design and prototyping process, several
safety issues surfaced, and would need to be dealt with well before the marketing and
manufacturing stage. As noted in the Safety and Reliability report, two of the important circuit
redesigns would be a diode circuit to prevent wall-wart reverse polarity issues and a fuse to
prevent large and dangerous current spikes that could result in a lethal conflagration. Also,
warning labels would need to be added to reiterate the cautioning of the LCD datasheet [5]: “If
the LCD panel breaks, be careful to not get the liquid crystal fluid in your mouth or eyes. Do not
eat the LCD panel”. Another concern with safety would be volume control. The device would
need to be tested to insure that the audio will not be able to be loud enough to injure the user. A
final safety consideration would be warnings for the users (included in the user manual) that
instruct them not to open up the device, and to let an expert handle it. Ethics demand that ALF
not only “avoid injuring others”, but also to avoid injuring the property of others. To this end,
ALF's design would need to be tested extensively with various external devices (headphones,
-22-
ECE 477 Final Report Spring 2009
speakers, audio input devices) to ensure that other products would not be ruined during use of
ALF.
6.3 Environmental Impact Analysis
Tied closely to ethics is environmental analysis, an important part of any product design. How
will the manufacturing process or normal use affect human health and their surroundings? How
should the device be properly disposed of to reduce environmental impact? Number one in the
IEEE code of ethics is a commitment “to accept the responsibility in making decisions consistent
with the safety health, and welfare of the public, and to disclose promptly factors that might
endanger the public or the environment”.
ALF's environmental impact is largely due to the printed circuit board and the LCD. The
manufacturing of PCBs affects human health and the environment in a number of ways. First,
the process involves hazardous materials such as arsenic, which is used to increase conductivity
of semiconductor material; hydrochloric acid, which is used for photoelectrochemical etching;
and lead, which is used in solder. These chemicals and materials often present serious health
risks to facility workers because of various waste streams, which often manifest themselves as
airborne particulates or industrial waste rinsewater [18].
To address these manufacturing environmental concerns, ALFs design could use as many
RoHS (Restriction of Hazardous Substances) compliant materials as possible, such as lead-free
solder. Unfortunately, lead-free solder might compromise the product lifetime because of
weaker and less effective solder joints. Another obvious way to reduce hazardous waste would
be to pack the board components as tightly as possible and design for a smaller board. It might
not seem useful for one board, but when considering the large numbers involved in
manufacturing, small reductions would add up quickly.
Once the device is past the manufacturing stage, the main environmental considerations come
from the consumer's use and disposal of the product. During the “normal use” stage of its
lifecycle, ALF would consume power and could potentially have its LCD screen broken. The
power consumption could be reduced by designing an efficient circuit, and also suggesting in the
user manual to unplug the device when it is not being used. The LCD screen issue could be
handled by placing a warning label on the device (as mentioned above in the ethical analysis
-23-
ECE 477 Final Report Spring 2009
section). ALF will be a passive “household” device and should not present substantial
environmental impact during normal use.
When the device has arrived at its deathbed, the PCB and LCD would require proper disposal,
which would be outlined in the user manual. Printed circuit boards can be recycled to recover
copper, nickel, tin, and lead [19]. Gold, palladium, and silver can also sometimes be recovered,
but in much smaller quantities. The LCD also has proper disposal paths. One way to recycle an
LCD is to incinerate it to generate glass substrates, which can be used as materials for buildings
and ceramics. Also, there are methods that are being developed for recycling the liquid crystals
themselves. [20] The user manual would just need to direct the user to the proper disposal
channels.
In addition to providing channels for recycling the PCB and LCD, the user manual would also
include general instructions for how to dispose of and recycle the other parts of the product. This
would involve the pushbuttons and the plastic enclosure.
6.4 Summary The ethical and environmental challenges that ALF faces are fairly easily managed. The most
important ethical considerations are honesty in device claims, device safety (for both users and
their products), and source code terms and conditions laid down by the GNU GPL. These
considerations come directly from the IEEE Code of Ethics. The first code of ethics provides the
link between ethics and the environment, and what is expected of a producer. The PCB and
LCD are the main sources of environmental impact, and are an issue mostly in the
manufacturing and disposal processes. The manufacturing impacts could be reduced by using
RoHS-compliant parts and by compacting the board. The proper disposal would be clearly
outlined in the user manual, and would involve recycling of both the PCB and the LCD.
-24-
ECE 477 Final Report Spring 2009
7.0 Packaging Design Considerations
7.1 Introduction
The project (hereafter referred to as ALF, which stands for Audio recording Losslessly on an
FPGA) will be able to receive an analog audio input, compress it into a FLAC file, and then
decompress the FLAC file for audio playback. ALF will have a line-in jack to accept analog
audio input for recording. In addition, there will be a line-out jack to connect audio output to
headphones or speakers for playback. ALF should also be able to store at least one minute of
compressed audio data in the onboard SDRAM. The user shall have an intuitive interface in the
form of pushbuttons and an LCD that will allow the user to control the record and playback
modes as well as cycle through information to be displayed on the LCD. The device packaging
will be large enough to contain the PCB board and all necessary components, yet portable
enough to be toted.
7.2 Commercial Product Packaging
Two commercial products that are similar to ALF are the Olympus LS-10 Linear PCM Recorder
and the Sony PCM-D50 Portable WAV Recorder. These two products have many features that
will be incorporated into ALF. One major difference is that the commercial products are both
handheld devices while ALF will be a table-top device.
7.2.1 Product #1
Product #1 is a digital audio recorder, the Olympus LS-10. The positive features include
24-bit/96kHz recording, a USB interface to a PC, multiple storage formats (WAV, MP3, WMA),
and 2 GB of internal Flash memory (as well as SD card capabilities) [6]. This is a strong contrast
ALF, which will include 16-bit/48kHz recording, FLAC format, and 16MB of internal memory.
However, the general packaging of both are very similar: an LCD display, user input buttons,
mic in, and headphone out. The LS-10 has a broader range of user controls, to complement its
greater functionality, but ALF will be simple and adequate. One major difference is that the LS-
10 is battery powered, but this is unnecessary for ALF because its purpose is for testing a
compression algorithm and a portable device is unnecessary. In addition, there are onboard
speakers, which are also superfluous for ALF. The LS-10 is standard (for a device of its type) in
durability and size, two packaging considerations that ALF will attempt to copy.
-25-
ECE 477 Final Report Spring 2009
7.2.2 Product #2
Product #2 is also a digital audio recorder, the Sony PCM-D50 Portable WAV Recorder. One
positive feature of this device is availability of multiple sampling rates: 22.05kHz, 44.1kHz,
48kHz, and 96kHz [7]. Like the first product, a USB interface is included for connecting to a
PC. However, there is no internal memory; the recorded audio is stored on an external flash
card. Once again, the general packaging is very similar. There is an LCD display, user input
buttons, mic in, and headphone out. Because of its greater functionality, the PCM-D50 also has
many controls that ALF does not have. The PCM-D50 is battery powered. Like ALF, the PCM-
D50 does not have onboard speakers. The PCM-D50 is standard in durability and size, two
packaging considerations that ALF will attempt to copy.
Table 7.1: Commercial Product Comparison
Item Product #1 Product #2
Cost $400 $600
Weight 165g 365g
Dimensions 131x48x22 mm 73x155x33 mm
Ports MIC in, Line in, Line out, USB
MIC in, Line in, Line out, USB
7.3 Project Packaging Specifications
Based upon commercial product packaging and the PCB board Footprint for ALF, ALF is
estimated to be approximately 7" long by 4" wide by 2” high (180mm x 100mm x 50mm). By
comparison to commercial products and based upon the approximate weights of the individual
components in the material list below, ALF is estimated to weigh about 15 oz. The LCD and
user interface pushbuttons are located on the front face of the device, while the mic in, line out,
and DC power jacks are on the side. A drawing of ALF can be found in Appendix A, and a table
of the packaging specifications can be found in Appendix B. The device enclosure will most
likely be made out of plastic, since containers or this sort can be easily purchased from Digi-
Key and are non-conductive so as to not cause accidental shorting of internal components.
-26-
ECE 477 Final Report Spring 2009
7.4 PCB Footprint Layout
The foremost component of the design is the FPGA, which will be the EP3C40. This was chosen
from among the various Cyclone III options because it has the fewest number of pins (240) and
is PQFP. An unnecessary excess of pins would only lead to an increase in soldering issues, and
the BGA packages of the other Cyclone IIIs would be nearly impossible with the available
equipment. The other major components (SDRAM, microcontroller, and Audio CODEC) were
chosen to have surface mount packages (TSOP, PQFP, SSOP) because a BGA could not be
soldered under our circumstances and DIP would be larger. ALF is not very constrained in size,
but choosing the smaller SOIC and SOP packages will make the design more compact, which is
desirable. An initial PCB footprint layout can be found in Appendix C.
7.5 Summary
It is not necessary for ALF to improve upon the packaging of current commercial products;
however, ALF will mimic their small size and durability. Since ALF is intended to only record at
specific parameters, its functionality will be limited. There will be 3 ports on ALF: 1 for DC
power in, a mic in, and a line out. Also, there will be an LCD and 3 pushbuttons. One negative
aspect of current commercial products is that the devices have numerous features and are often
difficult to learn to use. Because ALF is a simple design, this should be easily avoidable.
-27-
ECE 477 Final Report Spring 2009
8.0 Schematic Design Considerations
8.1 Introduction
ALF will be able to receive analog audio input, compress it into a FLAC file, and
subsequently decompress the FLAC file for audio playback. The audio input and output will
consist of line-in and lineout jacks, and an Audio CODEC chip that handles analog and digital
conversion. ALF will be able to store at least 30 seconds of compressed audio, which will be
stored in SDRAM; there will also be an RS232 connection for dumping the memory for external
viewing. The FPGA will do all of the audio compression and decompression internally, and will
handle all memory interfacing. Another feature of ALF is a user interface, consisting of an LCD
and three pushbuttons, for controlling the recorder and viewing relevant information. A
microcontroller will handle the pushbutton and LCD interface (via UART), and will
communicate with the FPGA through SPI.
8.2 Theory of Operation
8.2.1 Memory
The Cyclone III [2] will interface with an external 64 Mb (Megabit) SDRAM chip [3], whose
purpose is to store about half a minute of compressed audio. The FPGA is connected to the
SDRAM via a 12 bit address bus, 16 bit bidirectional data bus, and control flags. An SDRAM
module will be programmed into the FPGA to handle this communication. To allow for a
memory dump onto an external computer, a UART module will be programmed into the FPGA.
The purpose of this memory dump is to verify that the compression is correct. The UART will be
connected to an RS232 transceiver through a 3.3V to 5.0V level translator.
8.2.2 Audio Input/Output
The audio path consists of a line-in port, ADC, compression and decompression, DAC, and line-
out for playback. A Wolfson Audio CODEC [4] drives the line-in and line-out ports, and handles
all of the A/D and D/A internally, including programmable bits per sample and sample rate. The
audio codec will be configured by the FPGA using I2C, and will transmit data to and from the
FPGA using a left/right channel clock (96 kHz) for ADC and DAC, and a single data wire for
-28-
ECE 477 Final Report Spring 2009
ADC and DAC. A separate clock, BCLK (3.125 MHz), clocks the individual bits for the ADC
and DAC data.
8.2.3 User Interface
A PIC24F microcontroller [1] will be used to interface to the LCD [5] and pushbuttons, and
communicate with the FPGA through a 4-wire SPI. The PIC24F will connect to the LCD via
UART, with a 3.3V to 5V level translator in between to accommodate the 3.3V PIC output and
5.0V LCD input levels. The three active low pushbuttons will be connected to the
microcontroller via digital input pin.
8.2.4 Configuration/Reset
The FPGA will be configured using a USB Blaster cable via the active serial (AS)
programming interface [8]. In order to program the FPGA at startup, an EPCS16 EEPROM chip
will be used to store the code. ALF will use ICD2 to program the microcontroller. An active low
pushbutton will be used to reset the microcontroller. The microcontroller will then send an
asynchronous reset to the FPGA via a GPIO pin. Finally, the FPGA will reset the rest of the
components.
8.2.5 Power Supply and Voltage Regulation
ALF will be powered via a wall outlet. A wall-wart will be used to convert the 120V AC to 9V
DC which will power ALF via a DC power port. On the PCB the 9V rail will be regulated to 5V
using a Diodes Inc. AP1117 5V linear regulator. The LCD and MAX233 RS-232 driver are both
powered by the 5V rail. A ST LD1117 linear regulator will be used to regulate the 5V to 1.2V in
order to power the FPGA core. A Diodes Inc. AP 1120 linear regulator is a dual output regulator
that will regulate the 5V to 2.5V and 3.3V. The 2.5V rail will be used to power the
microcontroller core, and will also power the analog voltage inputs of the FPGA.
8.2.6 Clock Frequencies
A clock frequency of 100 MHz (generated by a crystal oscillator) will be used for the FPGA,
because it can not decouple a frequency faster than this and ALF needs to perform all the linear
-29-
ECE 477 Final Report Spring 2009
prediction and rice coding as fast as possible (to keep up with and outpace the audio sampling
rate of 44 kHz). If necessary, the FPGA can use one of its four PLLs to lower the clock
frequency to reduce skew between the SDRAM signals. Reducing skew is important because
during SDRAM transactions, all signals must be valid for a window of time. The SDRAM will
be run at 50MHz.
8.3 Hardware Design Narrative
The microcontroller will use one of the two available SPI controllers. The microcontroller
will be set up to be the master controller, and this interface will be used to communicate with the
FPGA. Also, a UART will be used by the microcontroller to send characters to the LCD, and
three ports will have to be inputs to receive the input from active low pushbuttons. Only the
transmit line of the UART will be used since the LCD does not send information back to the
microcontroller. On the FPGA, three main interface modules will be written; the FPGA will have
to connect to the microcontroller via SPI, will have an SDRAM module, and will use UART to
add the capability to dump information stored on SDRAM to a computer for debugging/testing.
An advantage to using an FPGA is that pin assignment can be done for all of the inputs and
outputs; ALF will be taking full advantage of this capability for connecting to the SDRAM (for
reasons described in 2.7). Final pin assignments will be determined during the layout process,
when the placement of the various chips is known. All of the SDRAM signals will be kept on
one side of the FPGA.
8.4 Summary
ALF's circuit will be designed to implement high quality audio compression and
decompression in an FPGA. ALF will be powered off a 9V DC input with a series of linear
voltage regulators that provide a stable power supply to the components. The FPGA, providing
most of the computational power for ALF, will sit at the center of the design. This will allow the
FPGA to interface directly to the microcontroller (user interfacing), SDRAM (compressed audio
storage), RS-232 driver (communicate with an external computer), and an audio CODEC chip to
provide ADC, DAC, and drive the line-in and line-out ports. The microcontroller will provide
the user interfacing via pushbuttons and the LCD.
-30-
ECE 477 Final Report Spring 2009
9.0 PCB Layout Design Considerations
9.1 PCB Layout Design Considerations - Overall
The FPGA is the main component of ALF, and thus is the centerpiece of the PCB. Since the
only analog signals are from the line-in/line-out connectors, the Audio CODEC chip should be
near the edge of the board (and near the connectors) to minimize the EMI from the analog
signals [10]. After the Audio CODEC, the quantized signals are passed to the FPGA for
compression. The I/O pins of the FPGA have been carefully configured to allow a direct path
from the Audio CODEC to the FPGA, allowing for some freedom when designing the PCB
layout; the Audio CODEC just needs to be placed on the correct side of the FPGA.
The SDRAM is a component that places many constraints on the layout. Because the
SDRAM [3] will be running at a high frequency (133 MHz), and because there are 38 traces that
connect the FPGA to the SDRAM, signal skew is a major concern; this issue can be addressed by
careful PCB layout. The SDRAM should be physically close to the FPGA, and all 38 pins should
be physically grouped together as much as possible. These two concerns can be addressed by
finding the largest set of unused I/O pins on one side of the FPGA. Unfortunately, there is no one
side that can accommodate the entire 38-pin parade. With this in mind, the key consideration will
be ensuring that the various SDRAM traces are fairly comparable in length, to prevent signal
skew. This can be accomplished by using a corner of the FGPA and centering the SDRAM along
the same corner.
On another side of the FPGA, there will be the microcontroller, the RJ-11 connector for ICD2
(to program the microcontroller) and the various components that it controls, namely the
pushbuttons and LCD. There are few PCB considerations here, given the low pin and external
component requirements for this part of the board. The remaining side of the FPGA will feature
the 100 MHz crystal oscillator and debugging components, such as the RS232 transceiver and
the header for FPGA debug pins.
The sheer number of components that will connect the FPGA, and the required proximity of
these components (especially the SDRAM and the decoupling capacitors) demonstrate the need
for a four-layer board. There will be a ground plane and a power plane, which will be split into
1.2V, 2.5V, 3.3V, and 5V sections, relieving the board of complicated power routing on the
-31-
ECE 477 Final Report Spring 2009
surface. The 4-layer board will limit PCB size, which was previously unconstrained. Now, the
board will have to stay within 30 square inches because of cost constraints.
9.2 PCB Layout Design Considerations - Microcontroller
The microcontroller has a 0.1 uF bypass capacitor, per the PIC24F datasheet [1], and an internal
oscillator (8MHz). There are few routing concerns with the microcontroller; it runs on 3.3V
alone, and uses only 15 of its 28 pins to connect to various components. For ALF, the FPGA will
have the most considerations. The needs for board centrality and closeness to SDRAM have
already been discussed. There will be one external crystal oscillator (100 MHz) that will be
placed as close to the FPGA as possible, to reduce the effect of the high frequency noise from the
oscillator, and also to preserve it from external noise.
The FPGA [2,9] will be placed such that it will overlap the 1.2V, 2.5V, and 3.3V sections of the
power plane, because it will be using all of these voltages. The presence of the power plane
sections will make the power trace routing local; there will simply need to be 50 mil power
traces (compared to 12 mils for normal traces) from the voltage regulators to the corresponding
power islands. The FPGA has 4 analog ground pins for the internal PLLs, and these will brought
to the outside of the FPGA using surface traces, then connected to a zero ohm resistor, which
will go to a digital ground section in the ground plane. The other analog circuitry (for line-out
and line-in) will be grounded to a dedicated analog section of the ground plane, which will then
connect to the aforementioned zero ohm resistor. This layout will provide isolation for the analog
and digital grounds, until they are linked at one point (the zero ohm resistor).
A major PCB design consideration for the FPGA is the large number of datasheet-specified
bypass capacitors. To create 1.2V and 2.5V "power islands", there will be a combination of a
ferrite bead and several parallel capacitors for each of the two levels to isolate the power from
the PLL voltage inputs. There will also be 28 0.1 uF capacitors for each 1.2V power/ground pair
and 14 0.1 uF capacitors for each 3.3V power/ground pair. Finally, there are 100 uF capacitors
between 3.3V supply and ground, and 1.2V supply and ground. All of these FPGA capacitors
will be placed as close to the corresponding pins as possible, and the routing will be local
because of the 1.2V, 2.5V and 3.3V power plane sections.
-32-
ECE 477 Final Report Spring 2009
9.3 PCB Layout Design Considerations - Power Supply
As mentioned previously, there will be a power plane split into 1.2V, 2.5V, 3.3V, and 5V
sections, which will each require a power trace of 50 mils on the surface from the corresponding
voltage regulator. The voltage regulators will be grouped together, with the 5V LDO supplying
the 1.2V, 2.5V, and 3.3V LDOs, and will be placed to minimize the power trace lengths.
Several capacitors will need to be placed next the voltage regulators to charge the bypass
capacitors in the rest of the circuit. Immediately after the 5V LDO, there will be a 220 uF
capacitor, and immediately after the rest of the LDOs will be 100 uF capacitors. The larger
capacitor (220 uF) will be used because of the higher current requirement thereafter, from each
of the other regulators and from the components that use a 5V supply. There might also be a 470
uF capacitor adjacent to the power terminals, for additional protection in case the previously
mentioned capacitors do not supply enough charge.
The ground plane will be split into various sections, to mirror the power plane configuration.
There will be an analog ground section for the audio circuitry between the Audio CODEC [4]
and the audio jacks. The CODEC chip, which has digital and analog circuitry, will straddle the
corresponding sections of the ground plane.
9.4 Summary
The printed circuit board layout for ALF consists of an FPGA at the center of the layout. The
FPGA interfaces with SDRAM, the microcontroller, and the audio CODEC all of which are
placed in close proximity. The SDRAM location of the SDRAM, in particular, was designed
such that the traces going to the FPGA were all of comparable length, so as to prevent signal
skew. Bypass capacitors for all of the components are placed immediately next to power pins to
supply clean, steady power to the components. There are 4 layers on the board. There are top
layer and bottom layers, which contain all of the components and signal traces. There are also
two inner layers, which consist of a ground plane and a power plane which is split into 1.2, 2.5,
3.3, and 5V sections. ALF will have a separate analog ground plane to reduce noise coupling on
the digital power lines.
-33-
ECE 477 Final Report Spring 2009
10.0 Software Design Considerations
10.1 Introduction
ALF allows a user to losslessly compress audio from a line-in and either store the
compressed file for later playback, or decode immediately to calculate the latency of the
compression algorithm. The audio will be compressed into the Free Lossless Audio CODEC
(FLAC) format, so that performance of the Rice Encoding method can be analyzed when
performed on an FPGA. The user will have four pushbuttons that are accessible, one to
begin/stop recording, one to play audio currently saved in internal memory, one to change what
is currently displayed on the LCD, and one to select either to save the audio into internal memory
or immediately decode the audio. There will be a small LCD to display to the user information of
interest about the audio, such as latency, size of file saved, and duration of recorded audio. There
will be a software reset button available only when the box is opened (not to the user) - as this
will be used only for debugging. If the user wishes to reset the software, a hard reset will need to
be performed by power cycling. All requests by the user will be initially handled by the
microcontroller, which will then pass any necessary information to the Field Programmable Gate
Array (FPGA). The FPGA performs all of the actual compression, decoding, and interfacing with
the Synchronous Dynamic Random Access Memory (SDRAM) and the left and right audio
channels via an Audio CODEC.
10.2 Software Design Considerations
The microcontroller has a total of 64 KB of flash program memory, and 8 KB of SRAM
available for use [1]. This is more than sufficient for the simple interfacing for which the
microcontroller will be used. The program flash memory is addressed from 0x0002000 to
0x00AC00. Any static data, such as text to be displayed on the LCD, can be stored here. The
FPGA is programmed via a Serial Configuration Device at power-up [2,8]. The Serial
Configuration Device is the equivalent to the program flash memory for the FPGA and is 16 KB.
It is connected to the FPGA as shown in Figure 1.
-34-
ECE 477 Final Report Spring 2009
Figure 10.1
Mapping of external interfaces:The following table describes the addresses of Ports/registers used:
Map Address Description
Timer 0x0100 through 0x0120 Timer registers used to set update LCD flag
UART 0x0220 through 0x0238 Registers for UART (used for LCD)
SPI 0x0240 through 0x0268 Registers for SPI (used to communicate to FPGA)
PortB 0x02CA-0x02CB Digital I/O pins for pushbuttons
RP0 0x06C1 Remappable Peripheral pin used to transmit data to LCD
RP1 through RP4
0x06C0, 0x06C2, and 0x06C3
Remappable Peripheral pins used for SPI controller
Table 10.1
Utilization of built in peripherals:
A SPI module, UART module, and Timer will be used by ALF. An 8-bit SPI will be used to
communicate information between the microcontroller and the FPGA; the microcontroller will
be the master controller. Control flags will be used to send appropriate information to the FPGA,
such as if compressed audio should be recorded, and to start or stop recording. The FPGA will
-35-
ECE 477 Final Report Spring 2009
only need to send three different types of information to the microcontroller to be displayed on
the LCD: size of the file in SDRAM, latency, and duration of audio. Data can be sent via SPI by
one of two methods; with a fixed packet length or variable packet length. The fixed packet length
will be easier to implement, but will set more constraints as to what data can be sent. The
variable packet length may be a little bit more complicated, but will allow a greater range of data
to be sent. Because there are three different types of data to be passed from the FPGA to the
microcontroller, the first 2 bits sent will be needed to declare what is being sent. If we do a
variable packet length, then the remaining 6 bits could be used to say how many packets to
expect. For a fixed packet length implementation, the 6 remaining bits (assuming just one
packet) would be actual data. Because the latency should not vary greatly, a fixed packet length
should be sufficient, and if need be a fixed packet length of 2 (instead of 1) will be used. The
UART module will only use the transmit signal and is what is used to control the LCD. The
Timer will be used to get new data for the LCD every second, so that the duration of the audio
can accurately be displayed.
Overall organization:
ALF will be flag-driven, with flags being set in response to a button being pressed. In essence,
there are only 5 flags to check, one for each pushbutton described earlier and one for the timer.
When the appropriate flag is set, information will be sent to the FPGA informing it to start/stop
recording, or to change whether or not to store the audio. When ALF is recording audio, it will
have to request the current average latency (calculated by the FPGA). The rationale behind using
this kind of organization is that ALF should begin/stop recording very soon after a button being
pressed, and because there are only 5 flags (and very little overhead in any given cycle) the loop
should execute quickly.
FPGA:
Because of the design of an FPGA, there are no particular ports or registers to be concerned
with. Some controllers will be available through SOPC Builder and will allow quick progress. In
specific, an SDRAM core controller has been found and tested. The FPGA will need to have a
SPI controller, UART controller, and I2C controller. The architecture is included in Appendix B
to show the general layout, and code is more thoroughly discussed in section 3.
-36-
ECE 477 Final Report Spring 2009
Debugging:
We have 10 GPIOs available as headers to use through the FPGA. The FPGA will also have a
UART controller solely so that we have the ability to dump the data stored in SDRAM onto the
screen. This will be used to prove that the saved data is in the flac format. If need be, there are
more IO pins to be used on the FPGA, however they are currently not going to a header, so this
will be avoided. On the microcontroller side, the LCD can be used (once functional) as a
debugging tool, in addition to the In-circuit Debugger that we have available for use as well.
10.3 Software Design Narrative
10.3.1 Microcontroller Code
Main Loop (C code):
The microcontroller's main purpose is to interface with the user. Within the main loop, there is
a switch statement with code to run each different menu within each case. There are six different
menus total. Thus, there are six different case statements. They consist of the record, playback,
streaming, memory, volume, and effect menus. Some of menus can only be accessed during
certain functions. For instance, the effects menu, can only be accessed when the audio is
streaming.
Timer Interrupts (C code)
Cases are toggled between by hitting one of the pushbuttons. The microcontroller scans the
pushbuttons within one of the two timer interrupt service routines described below. If the
pushbutton is hit, the ISR sets flag corresponding to that pushbutton. There are two timer
interrupts in the microcontroller. The first is set to interrupt every 5ms and scan the 3
pushbuttons ALF has. The other timer interrupt is set to cause an interrupt every 1 second. It is
used to increment the counter which is displayed when ALF is recording, streaming, or playing
audio.
SPI (C code)
The microcontroller communicates with the FPGA via sending 8 bit SPI signals. The
microcontroller is the master and the FPGA is the slave. The microcontroller has 7 different
commands that it sends to the FPGA. These commands are start or stop recording, start or stop
playback, start or stop streaming, and flange audio. The SPI signals are sent using by sending the
correct command in the form of a decimal number to a ‘SPI send’ function borrowed from the
-37-
ECE 477 Final Report Spring 2009
development board sample code. This function places the command to be sent in the correct
register and then waits until the command has been sent so that another command send attempt
cannot be made until the first command is sent.
LCD (C code):
The LCD is used to display each different menu and provide the user with the option to make
selections within each menu. The microcontroller communicates with the LCD via UART. The
UART command ‘transmit’ function was also borrowed from the development board sample
code. This function ensures that the UART buffer is empty and then puts the command to be sent
in the transmit buffer. This register sends one letter at a time to the LCD, so there are also
functions implemented which can send entire words as well as numbers. All letters and other
special commands have ascii values which are actually what is sent over the UART. The LCD
data sheet provides the ascii values for all of the letters as well as the special commands, such as
return, backspace, and other non-alphanumeric characters.
10.3.2 FPGA Code
ALF (VHDL)
This is the top level entity and does all the port mapping of the other components. The
internal signals that also determine what audio data is sent to the CODEC are also defined.
Sound (VHDL)
This is a component that connects the top level component to two smaller components,
CLOCK_500 and I2C, that are used to configure the Audio CODEC. This component is fully
implemented.
CLOCK_500 (Verilog)
This component creates the signal that will be the clock for the I2C component. It also
determines what data will be sent to the CODEC for configuration. When the user requests to
change the volume, this is the component that does it by changing the value in the register. It was
modified from an Altera tutorial to fit our needs. This component is fully implemented.
I2C (Verilog)
This component takes the data from CLOCK_500 and sends it out via the I2C protocol to the
codec. It is a very lightly modified version of one found in an Altera tutorial. This component is
fully implemented.
-38-
ECE 477 Final Report Spring 2009
getData (VHDL)
This component is what captures the data from the CODEC. When there’s a transition on the
ADC clock, a shift register is used to capture the 16 bits from the CODEC. Once a full 16 bits
has been read, a flag is asserted to let any components connected to it that new data has been
read. This component is fully implemented.
sendData (VHDL)
When audio data is being streamed, the audio data from getData is passed here. A shift
register is used send an audio data bit on the Clock being generated by the CODEC. sendData
sits in an IDLE state until a transition on the DAC Clock. This component is fully implemented,
but could likely be absorbed by the sendRecordedAudio component.
itrptSPI (VHDL)
This component takes the data captured from the SPI and sets a command that is used to
determine whether sendData or sendRecordedAudio is used as well as whether to simply stream
audio, record audio, play recorded audio, or stream audio with a flange effect. While currently
fully implemented, this component would need to be updated if more capabilities were added.
Delay (VHDL)
The delay.vhd module implements the flange effect on streaming audio. It takes 16-bit streaming
data in from getData, passes it through a circular buffer, then adds the delayed input to the
current input and outputs to SendRecordedAudio. The circular buffer is onchip memory (1 port
ram), accessed through ram.vhd, which is created by the Altera megafunction wizard. The
memory is large enough to delay the input approximately 30 - 50 milliseconds. The delayed
input is scaled by a gain (less than one), and added to the current input. The entire module is a
state machine that acts based on signals from getData and SendRecordedAudio that indicate 16-
bit data is available for reading and writing, respectively. This component is fully implemented.
SendRecordedAudio (VHDL)
SendRecordedAudio is very similar to SendData but where sendData is used to interface to
getData, sendRecordedAudio is used in conjuction with either memory or with the delay
component. When in an idle state and in a mode where audio should be either read for memory
or manipulated, this component waits to be informed that new data is ready to be sent to the
CODEC. When there is new data ready to be sent to the CODEC, sendRecordedAudio stores this
data has in a register. After this, sendRecordedAudio waits for a transition on the DAC clock and
-39-
ECE 477 Final Report Spring 2009
then shifts out the 16 bits based on a clock generated by the CODEC. Once this is done, a flag is
set to inform the appropriate component that new data is being requested. This component is
fully implemented.
Compress
This component is currently not implemented, but would have been used to take in one block
of audio data (4096 samples) and compress it using the FLAC format. In addition, a flag would
need to be asserted to inform a timer that would be used to determine latency to start counting.
Decode
Once a block of audio was compressed, this component would be used to immediately decode
it. When it was done, a flag would need to be asserted to inform a timer to stop counting. This
timer would then tell us the number of clock cycles it took to compress and then decode a block
of audio. This component is currently not implemented.
SPI (Verilog)
This is a normal shift register, with one exception. Due to the fact that an FPGA clock is
much faster than the micrcontrollers clock, this component oversamples the SPI data to ensure
that good data is read. Currently only used to receive data, but tested for both sending and
receiving data. This code is slightly modified from code found online at
http://www.fpga4fun.com/SPI2.html. This component is fully functional.
sdram (Verilog)
This component does the necessary port mapping for sdram_rw, sdram_pll. And
sdram_controller. The PLL takes a 50 MHz clock as input and outputs two 133 MHz clocks and
one 50 MHz clock. One of the two 133 MHz clock has a 3 ns delay for communication with the
SDRAM chip. This code is lightly modified code from
http://whoyouvotefor.info/altera_sdram.html.
sdram_rw (Verilog)
This component is what is used to read and write to the sdram controller. It is heavily
modified code from http://whoyouvotefor.info/altera_sdram.html. While fully functional and
implemented, variable names could be renamed more appropriately, and the code could be
cleaned up in general. There are currently two inferred latches, however these do not affect the
performance of the code and are created because the registers are only assigned in conditional
logic (however, it is set up in a manner that does not create problems).
-40-
ECE 477 Final Report Spring 2009
sdram_controller (Verilog)
This component is very slightly modified code from
http://whoyouvotefor.info/altera_sdram.html. This is what handles the initialization of SDRAM,
refreshing of the SDRAM, and the control signals necessary for SDRAM. No further changes
should be necessary.
10.4 Summary
This report has shown how design considerations have guided our choice to use a flag-driven
method for the microcontroller, and what peripherals to implement. The locations of important
ports and registers have identified in the microcontroller, and the architecture layout of the
FPGA has been included in the appendix and described throughout the Software Design
Narrative. The options for debugging have been addressed. The hierarchy of code has been pretty
thoroughly thought out which will hopefully help out given the short time remaining to program.
As time permits, some things may be optimized, such as the piping of audio described above.
-41-
ECE 477 Final Report Spring 2009
11.0 Version 2 Changes
In a second iteration of ALF, a JTAG connection would be included to allow 1) a means of
programming the FPGA directly for debugging and 2) allow the addition of a NIOS II Softcore
processor, thereby entirely eliminating the need for a micrcontroller. The code would likely have
to be revised, but the cost of doing that would likely be worth removing additional circuitry (and
removing the additional places for things to go wrong). The NIOS II Processor is also necessary
if IP cores (such as a UART module) were to be added in through the SOPC builder. In addition,
SDRAM would likely be replaced by something that would allow a larger amount of audio
recorded, such as an SD card interface. This would again require a large amount of
reprogramming, but would be worth it from the perspective of usability for the end user, and also
allows a much larger amount of space to store data. This would give the end user the ability to
use the device to decode flac files downloaded on a computer as well. If this change is made, it
allows easier access for a programmer to see what is stored in memory for debugging if
necessary. A heat sink would likely be included on the 5V regulator as well; the LCD can draw a
large amount of current, and the voltage drop from 9V to 5V is large enough that a large amount
of heat is produced when in an enclosed box. The ability to implement other audio effects could
also be added, such as filters or reverb. The most obvious addition would be the ability to
compress and decompress audio. If possible, it would be done entirely in HDL to allow for as
much parallel processing as possible, and because this would allow a greater number of clock
cycles to perform the compression (as opposed to in a microcontroller). As a last resort, the
NIOS II processor could be used to implement the C code necessary for compression. However,
the desire is that eventually the entire process would be done in HDL.
-42-
ECE 477 Final Report Spring 2009
12.0 Summary and Conclusions
In the process of designing ALF, new knowledge was learned, old knowledge was reinforced,
and much experience was gained. All team members were able to learn from the experience of
rationalizing what components were needed, how design constraints led to part selection, the
process of connecting them all in a schematic, and then converting that schematic into a layout.
Some team members gained knowledge on proper care of soldering irons, as well as how to
properly solder components as small as our 40 mil by 20 mil capacitors. A great deal of
knowledge of VHDL was gained by some, while strongly reinforced for others. Some team
members gained substantial knowledge and experience in programming microcontrollers with C.
Lastly some gained a great deal of knowledge in understanding how to interface with other
devices, and what information to look for in datasheets. This is exemplified by interfacing with
SDRAM or with the Audio CODEC.
In addition to technical knowledge, team members were able to gain knowledge and
appreciation for a design process in general. All team members had learned by the end of the
semester that no matter how early a project is started, it is always beneficial to have started
sooner. There is a delicate balance that must be met between pushing forward towards
completion in a project, and carefully planning out the design. If too much time is spent thinking
about the 'best way' to do a project, there will simply not be enough time to implement any
method. However, if one recklessly starts working on a problem, a great deal of time and effort
can be wasted on problems that would be easily avoidable. One such example is that ALF had to
be programmed using the Active Serial interface. This takes a great deal longer than
programming using the JTAG interface, and the time spent waiting for the configuration to erase
and be reprogrammed can quickly add up to be a significant amount of time. Also, if a problem
is not thought out thoroughly enough, major revisions may be necessary in the future that could
eliminate previous work; an example being the possible elimination of the microcontroller or
replacing SDRAM with an SD card interface. As team members move from the 'academic world'
to the 'real world' greater stress will be placed on things like economic, ethical, environmental, or
safety consequences; things not normally considered in academic work. This project allowed the
team members to be further exposed to this before being responsible for them in the work force.
-43-
ECE 477 Final Report Spring 2009
13.0 References
[1] Microchip. PIC24FJ64GA004 Family Data Sheet. 2008. [Online]. Available:
http://ww1.microchip.com/downloads/en/DeviceDoc/39881c.pdf. [Accessed Feb. 2008].
[2] Altera. Cyclone III Device Handbook, Volume 2. Jan 2008. [Online]. Available:
http://www.altera.com/literature/hb/cyc3/cyc3_ciii52001.pdf. [Accessed Feb. 2008].
[3] Integrated Silicon Solution, Inc. IS42S16400 Data Sheet. Jan. 2008. [Online]. Available:
http://www.issi.com/pdf/42S16400.pdf. [Accessed Feb. 2008].
[4] Wolfson Microelectronics. WM8731 Data Sheet. Aug. 2008. [Online]. Available:
http://www.wolfsonmicro.com/uploads/documents/en/WM8731.pdf. [Accessed Feb. 2008].
[5] Crystalfontz. CFA-632 Serial LCD Module Data Sheet. Oct. 2005 [Online]. Available:
http://www.crystalfontz.com/products/632/datasheets/34/CFA-632_v2.0.pdf. [Accessed Feb.
2008].
[6] Olympus. LS-10 Specifications. 2009. [Online]. Available:
http://www.olympusamerica.com/cpg_section/product.asp?product=1350&fl=4. [Accessed:
February 2009].
[7] Sony. PCMD50. [Online] Available: http://pro.sony.com/bbsc/ssr/product-PCMD50.
[Accessed: February 2009].
[8] Altera. USB Blaster User Guide. April 2008 [Online]. Available:
http://www.altera.com/literature/ug/ug_usb_blstr.pdf. [Accessed Feb. 2009].
[9] Altera. Pin Information for the Cyclone III EP3C40 Device. 2008. [Online]. Available:
http://www.altera.com/literature/dp/cyclone3/EP3C40.pdf. [Accessed Feb. 2009].
[10] Motorola. 1995. [Online]. Available:
https://engineering.purdue.edu/ece477/Homework/CommonRefs/AN1259.pdf. [Accessed Feb.
2009].
[11] Free Patents Online Patent: 7430328 Inventor: Stephen Cooley. Date Filed: Dec. 01, 2004.
Available: http://www.freepatentsonline.com/7430328.html
[12] Free Patents Online Patent: 5884269 Inventor: Claude Cellier. Date Filed: Apr. 17, 1995.
Available: http://www.freepatentsonline.com/5884269.html
-44-
ECE 477 Final Report Spring 2009
[13] Free Patents Online Patent: 20060010151 Inventor: Star Sung. Date Filed: May 25, 2004.
Available: http://www.freepatentsonline.com/y2006/0010151.html?
query=free+lossless+audio+codec&stemming=on
[14] Diodes Inc. AP1117. Mar 2009. [Online]. Available:
http://www.diodes.com/datasheets/AP1117.pdf. [Accessed Feb. 2009].
[15] MIL-HDBK-217F Military Handbook—Reliability Prediction of Electronic Equipment.
[Online]. Available: https://engineering.purdue.edu/ece477/Homework/CommonRefs/Mil-
Hdbk-217F.pdf. [Accessed Apr. 2009].
[16] IEEE Code of Ethics. IEEE. Feb 2006. [Online]. Available:
http://www.ieee.org/portal/pages/iportals/aboutus/ethics/code.html [Accessed Apr 2009]
[17] GNU General Public License. GNU Operating System. Jan 2009. [Online]. Available:
http://www.gnu.org/copyleft/gpl.html [Accessed Apr. 2009].
[18] J. Holden and C. Kelty. “The Environmental Impact of the Manufacturing of
Semiconductors.” May 2007. [Online]. Available: http://cnx.org/content/m14503/latest/
[Accessed Apr 2009].
[19] M. Tarr. “PCB Recycling Issues.” [Online]. Available:
http://www.ami.ac.uk/courses/topics/0113_prei/index.html [Accessed Apr 2009].
[20] “Recycling Activities”. LCD Industries Research Committee. [Online]. Available:
http://home.jeita.or.jp/device/lirec/english/enviro/recycle.htm [Accessed Apr 2009].
-45-
ECE 477 Final Report Spring 2009
Appendix A: Individual Contributions
A.1 Contributions of Andrew Hartnett:
Andrew was labeled as the “team leader” on documents, however had to perform very few of the
tasks normally assigned to a leadership position. This is due to the delightful fact that the team
was able to work independently smoothly (and efficiently) while still communicating with one
another, Andrew usually just tried to be informed well enough on what other team members were
doing to make sure integration of parts went smoothly, as well as remind team members of
deadlines for things such as notebook captures.
At the beginning of the semester, Andrew is the one that found a template, and set up the
structure of the website. He also maintained the website as necessary, adding in pictures, putting
links to documents, or updating information on the website throughout the semester.
As the only computer engineer on the team, Andrew’s was mainly tasked with assessing the
feasibility of goals from a programming standpoint, and setting up the overarching architecture
for software. In regards to assessing the feasibility of goals, he was unfortunately unable to
correctly estimate the time necessary to complete all of the tasks. However, given enough time, it
is likely that the code necessary for the intended function would have been manageable. As the
only person with a class on Hardware Description Language, it was also Andrew’s responsibility
to assess what could and could not be done in an FPGA. After initially helping to set up some
things on the microcontroller, he was able to focus all programming efforts on writing VHDL
and Verilog code for the FPGA. While Curt did most of the work in configuring the CODEC,
Andrew was able to store the incoming data in registers, and wrote the code for sending the
appropriate data to the CODEC. After Curt and Andrew found some code for interfacing with
SDRAM, Andrew was able to modify it for use with the specific intent for the project. Since
Andrew was the only one with a class in VHDL, he was also tasked with assisting Curt, the other
VHDL programmer on the team, when necessary. If given the opportunity, Andrew would have
started programming earlier than what he did; the time left in the semester by the time the PCB is
designed is simply not enough to do what the team had set out to do at the beginning of the
semester.
A-1
ECE 477 Final Report Spring 2009
When writing up reports (which was typically worked on as a team effort), Andrew was the one
that would start the reports and add all the initial information in the reports. This would then later
be cleaned up and revised by the rest of the team.
A.2 Contributions of Curt Schieler:
For the first few weeks of the design process, Curt and the other team members shared roles and
worked together to create a collaborative initial effort, in both system design and report writing.
In the beginning, Curt was labeled as one of the team members who would concentrate on
hardware and compression; as the semester progressed, he shifted to FLAC and programming
VHDL. Also, Curt assumed the non-technical but satisfying role of report editor throughout the
semester.
After the PCB design process, Curt worked on a number of things with Andrew, and also worked
through the FLAC source code to gain a complete understanding in order to be able to implement
the algorithms in VHDL. With Andrew, Curt investigated many options for SDRAM, including
online code and a soft core processor in the FPGA that would contain an SDRAM core
controller. Finally, they found code online that Andrew was able to modify. Curt also worked to
interface with the Audio CODEC, which involved understanding the datasheet with all of its
timing requirements, configuration options, and I2C and audio data transfer protocols. While
Andrew wrote the bulk of the VHDL code to interface with the CODEC, Curt assisted in the
debugging process and was able to learn VHDL by doing so.
In addition to working with Andrew on the SDRAM and CODEC, a large part of Curt's
contribution was with FLAC, which was not featured in the final device. Going through FLAC
source code was a daunting but essential part of working towards implementing FLAC in
VHDL, and took more time than expected because of the code complexity and complete lack of
documentation. As Curt started to understand all of what was involved in FLAC (linear
prediction, rice encoding, subframe length minimization, etc.), he saw how much more there was
than first met the eye, and that many of the algorithms involved were inherently serial (not very
compatible with the parallel nature of an FPGA). Curt designed a architecture for the entire
process, and wrote VHDL modules for Rice encoding and the first part of the linear prediction,
but realized that FLAC was not going to be achievable in the time that was remaining. Given
A-2
ECE 477 Final Report Spring 2009
more time and a solid understanding of VHDL and how to debug VHDL code, Curt would have
been able to create a skeletal implementation of FLAC. After realizing that FLAC was not
achievable, Curt used his new-found VHDL knowledge to write a module that implemented
flanging, an audio effect similar to an echo. If given the opportunity, Curt would have started
learning VHDL and going through the FLAC source code much earlier in the semester.
A.3 Contributions of David Eslinger:
In the beginning of the semester, David met with the rest of the team in order to do the initial
planning of the project. He helped determine the Project Specific Success Criteria which
established exactly what the project needed to accomplish. Based on these success criteria,
David and the other team members researched the various components needed to accomplish the
project goals. The research was focused on the major components, such as the FPGA,
microcontroller, memory, and A/D and D/A converters. Once the major components were
selected, the initial packaging was designed. While Ken made the CAD drawing, David helped
determine the placement of the components. David then drew the initial block diagram for the
system. During the first few weeks, the team also wrote several papers to report on the progress
of the project. David helped with these reports by doing research and proofreading.
The next major step in the design process was to draw the schematic. David was the team
member with the most experience in working with OrCAD Capture and was therefore delegated
the task of drawing the schematic. He made schematic symbols as needed or downloaded
symbols from the manufacturers. Most of the time drawing the schematic was spent figuring out
how to connect the FPGA to the rest of the system. While David focused on the FPGA, his team
members read the data sheets for the other components and then worked with David to draw
those sections of the schematic. As changes to the design were made throughout the semester,
David was the one delegated with the task of keeping the schematic up to date.
Once the schematic was drawn, the PCB layout needed to be made. Once again, David was the
team member with the most experience in working with OrCAD Layout, and therefore made the
layout with inputs from the other team members. Several versions of the layout were made
before the design was ready to be manufactured. First David used temporary footprints for the
components in order to get a general idea of the layout. With Andrew's help, David reassigned
A-3
ECE 477 Final Report Spring 2009
some of the FPGA pins in order to reduce the amount of traces going from one side of the board
to the other side. As the chip packages of the components were finalized, David fixed the layout
footprints and rerouted traces as necessary. He spent several hours routing the SDRAM to the
FPGA, and several more hours routing all of the bypass capacitors for the FPGA. He also
figured where the power and ground planes would be needed. After the design review, several
changes were made to the schematic which resulted in major changes necessary for the layout.
David then rerouted the entire board keeping in mind how the power and ground planes would
work. Once the PCB was manufactured and all of the parts were in hand, David populated the
board.
While David was dealing with the hardware, much work was being done by the other team
members on the software. However, the FPGA and microcontroller were still unable to
communicate with each other. David then found an SPI receiver written in Verilog and modified
it to work with the project. He then worked with Andrew and Ken to get the SPI communication
working correctly between the two chips. Once that was done, David helped with debugging the
rest of the code.
A.4 Contributions of Ken Pesyna:
Towards the beginning of the project, Ken worked with the rest of the team to come up with a
tractable and novel project design. Ken worked to help put together the project proposal and
determine the subsequent design constraints. After the project design was set, he spent a good
amount of time researching major hardware components to be used in the design. Components
researched were A/D and D/A converters, the FPGA, the SDRAM, VCXO, and the
microcontroller. Ken also worked to acquire a development board for our microcontroller so that
programming could be started before the completion of the PCB.
Ken spent much of the time in the early project build stage compiling lists of final components to
be ordered. Once the major components were decided upon and the schematic was completed,
Ken put together a list of links and quantities of all parts which needed to be ordered. The most
time consuming part of this process was determining appropriate sizes of capacitors and resistors
which were needed and if they were available to order. Ken worked largely with David who was
A-4
ECE 477 Final Report Spring 2009
putting together the PCB layout to determine these sizes. After the final list of components was
compiled, Ken communicated these needs with Mark Brooks at our sponsoring institution,
Southwest Research Institute (SwRI). Mr. Brooks then insured these parts were ordered and sent
to our team.
Ken also spent time coming up with the packaging design for ALF. Ken put together a drawing
using Catia CAD software of our packaging which encompassed. After the PCB footprint was
finalized, Ken used this information to find packaging which would big enough to easily
encompass the board, yet also be small enough so that space was efficiently used. During the
PCB layout process, Ken spent much of his time drawing up custom footprints of non-
standardized parts which were needed in our layout. Footprints which needed to be drawn were
footprints for the line-in and line-out jacks, crystal oscillator, power jack, and reset pushbutton.
During the software design process, Ken worked largely on the microcontroller programming.
Programming consisted of putting together code which allowed the microcontroller to
communicate with the LCD via UART, code which allowed the microcontroller to communicate
with the FPGA via SPI, code which allows user input via pushbuttons, and code which put
everything together in a intuitive menu system that allows the user to control the functions of the
project. Since the FPGA and microcontroller operate at different clock frequencies, much of
Ken's time in this process was spent working with Andrew and David to get the SPI
communication working correctly between the two chips.
A-5
ECE 477 Final Report Spring 2009
Appendix B: Packaging
Figure B-1. 3-D view of product packaging.
B-1
6.3 in
2.4 in
6.3 in
ECE 477 Final Report Spring 2009
Appendix C: Schematic
Figure C-1: Microcontroller, FPGA, Level Shifter, Pushbutton and LCD headers, EEPROM, UART, Oscillator, Reset
C-1
ECE 477 Final Report Spring 2009
Appendix D: PCB Layout Top and Bottom Copper
Figure D-1: PCB Top
D-1
ECE 477 Final Report Spring 2009
Appendix E: Parts List Spreadsheet
Vendor Manufacturer Part No. Description Unit Cost Qty Total Cost
Digi-Key Altera EP3C40 Cyclone III FPGA 78.50 1 78.50
Digi-Key Microchip PIC24FJ64GA004 16-bit microcontroller 5.93 1 5.93
Digi-Key ISSI IS42S16400 SDRAM 4.81 1 4.81
crystalfontz Crystalfontz CFA632YFBKS LCD 37.00 1 37.00
Digi-Key Connor-Winfield CWX823-100.0M Oscillator 3.11 1 3.11
Mouser Wolfson WM8731SEDS Audio CODEC with headphone driver and programmable sample rates
3.35 1 3.35
Digi-Key CUI Inc SJ-3523-SMT Audio Jack .87 1 .87
Digi-Key Diodes Inc AP1117E50G-13 5 V Regulator .77 1 .77
Digi-Key Diodes Inc AP1120SL-13 2.5V/3.3V Regulator .51 1 .51
Digi-Key Diodes Inc LD1117S12TR 1.2V Regulator .77 1 .77TOTAL $135.62
E-1
ECE 477 Final Report Spring 2009
Appendix F: Software Listing
Microcontroller Code---Main.c---
/* The microcontroller's main purpose is to interface with the user. Within the main loop, there is a switch statement with code to run each different menu within each case. There are six different menus total. Thus, there are six different case statements. They consist of the record, playback, streaming, memory, volume, and effect menus. Some of menus can only be accessed during certain functions. For instance, the effects menu, can only be accessed when the audio is streaming. */
#include "system.h"
// Setup configuration bits#ifdef __PIC24FJ64GA004__ //Defined by MPLAB when using 24FJ64GA004 device_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx1 & IOL1WAY_ON) _CONFIG2( FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_PRI & I2C1SEL_SEC)#else_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2) _CONFIG2( FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_PRI)#endif
//Initialize variablesint cnt = 0;int counting = 0;int write = 1;int begin_timer = 1;char * word = "Duration \0";char * playDuration = "Duration \0";int menu = 2;int prevmenu = 2;char * pushStart = "Start Recording\0";char * pushStop = "Stop Recording\0";char * pushStopPlay = "Stop Playing\0";char * pushStartPlay = "Start Playing\0";char * storage = "Storage \0";char * saveAudio = "Internal mem \0";char * imDecode = "Immed. decode \0";char * playAudio = "Playback \0";char * record = "Record \0";int pb1 = 0;int pb1prev =0;int pb2 = 0;int pb2prev=0;int pb3=0;int pb3prev=0;int pb4=0;int pb4prev=0;int storeStatus = 1;int firstTime = 0;int firstCase = 0;int memory = 0;int startuptimer = 0;int latency = 0;
F-1
ECE 477 Final Report Spring 2009
int testspi = 0;int volumestatus = 8;int volumecounter = 0;int effect = 0;int menulast = 2;
int main(void){//Unlock registersasm volatile ( "MOV #OSCCON, w1 \n""MOV #0x46, w2 \n""MOV #0x57, w3 \n""MOV.b w2, [w1] \n""MOV.b w3, [w1] \n""BCLR OSCCON,#6");
RPINR20bits.SDI1R = 4;//configure SPI Data In (MISO) line to RP4 (pin 11)RPOR0bits.RP0R = 3;//configure UART1 transmit to RP0 (pin 4)
RPOR1bits.RP3R = 7;//configure SPI Data out (MOSI) line to RP3 (pin 7) RPOR1bits.RP2R = 8;//configure SPI clock line to RP2 (pin 6)
//lock registersasm volatile ( "MOV #OSCCON, w1 \n""MOV #0x46, w2 \n""MOV #0x57, w3 \n""MOV.b w2, [w1] \n""MOV.b w3, [w1] \n""BCLR OSCCON,#6");
//Setup PortB IOs as digital in for pushbuttonsAD1PCFG = 0xffff;TRISB = 0xffff;TRISBbits.TRISB6 = 0;PORTBbits.RB6 = 0;TRISBbits.TRISB8 = 0;PORTBbits.RB8 = 1;
// Setup the UART UART1Init();
// Setup the SPI SPIMPolInit();
// Setup the timerTimerInit();
// Setup the LCDmLCDInit();//BannerStart();mLCDPutCmd(12);
//Wait 1 second for LCD to initializewhile(!startuptimer){}
UART1PutChar(14);
F-2
ECE 477 Final Report Spring 2009
UART1PutChar(40); UART1PutChar(15); UART1PutChar(40); UART1PutChar(4); int once = 0; PORTBbits.RB8 = 0; asm volatile ("nop"); PORTBbits.RB8 = 1; SPIMPolPut(15); SPIMPolIsTransmitOver(); mSPIMPolGet(); SPIMPolPut(20); SPIMPolIsTransmitOver(); mSPIMPolGet();
//Main Loop while (1) { //Change to next available menu if(pb3) { pb3 = 0; firstCase = 0; once = 0; begin_timer = 0; firstTime = 0; if(!counting) { menulast = menu; menu++; //Increment menu menu %= 5; } else if(menu!=0 && menu !=4 && menu != 5) { menulast = menu; menu = 4; } else if(menu == 4 && menulast ==1) { menu = menulast; } else if(menu == 4 && menulast == 3) { menu = 5; } else if(menu == 5) { menu = 3; } } //Switch statement to switch between menus switch(menu) { //Record Menu case 0: if(!storeStatus) { menu = 1;
F-3
ECE 477 Final Report Spring 2009
break; } if(pb1 && !counting) { SPIMPolPut(5); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); counting = 1; cnt = 0; UART1PutChar(17); UART1PutChar(7); UART1PutChar(0); printCounter(cnt/60); UART1PutChar(58); printCounter(cnt%60); TMR1 = 0x00; pb2 = 0; begin_timer = 1; } if(pb2 && counting) { SPIMPolPut(10); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); begin_timer = 0; counting = 0; pb2 = 0; } if(!counting && !once) { UART1PutChar(12); printString(record); printCounter(cnt/60); UART1PutChar(58); printCounter(cnt%60); UART1PutChar(10); UART1PutChar(13); printString(" start \0"); UART1PutChar(148); printString("stop \0"); once = 1; }
F-4
ECE 477 Final Report Spring 2009
break;
//Playback menu case 1: if(!storeStatus && !counting) { menu = 2; break; } if(pb1 && !counting) { SPIMPolPut(15); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); counting = 1; //cnt = 0; UART1PutChar(17); UART1PutChar(9); UART1PutChar(0); printCounter(cnt/60); UART1PutChar(58); printCounter(cnt%60); TMR1 = 0x00; pb2 = 0; begin_timer = 1; } if(pb2 && counting) { SPIMPolPut(20); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); begin_timer = 0; counting = 0; pb2 = 0; } if(!once) {
UART1PutChar(12); printString(playAudio); printCounter(cnt/60);
F-5
ECE 477 Final Report Spring 2009
UART1PutChar(58); printCounter(cnt%60); if(!counting) { UART1PutChar(10); UART1PutChar(13); printString(" start \0"); UART1PutChar(148); printString("stop \0"); } else { UART1PutChar(10); UART1PutChar(13); UART1PutChar(148); printString("start \0"); printString(" stop \0"); } once = 1; } break;
//Storage Menu case 2: if(!firstCase) { UART1PutChar(12); printString(storage); UART1PutChar(10); UART1PutChar(13); printString(" SDRAM No Mem\0"); firstCase = 1; if(!memory) { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); } else { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); } }
if(pb2 && !memory)
F-6
ECE 477 Final Report Spring 2009
{ UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); memory = 1; storeStatus = 0; pb2 = 0; } if(pb1 && memory) { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); memory = 0; storeStatus = 1; pb2 = 0; } break;
//Stream Audio Menu case 3: menulast = 3; if(storeStatus && !counting) { menu = 4; break; } if(pb1 && !counting) { SPIMPolPut(25); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); counting = 1; cnt = 0; UART1PutChar(17); UART1PutChar(10); UART1PutChar(0); printCounter(cnt/60); UART1PutChar(58); printCounter(cnt%60);
F-7
ECE 477 Final Report Spring 2009
TMR1 = 0x00; pb2 = 0; begin_timer = 1; } if(pb2 && counting) { SPIMPolPut(30); SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); begin_timer = 0; counting = 0; pb2 = 0; cnt = 0; effect = 0; } if(!once) { UART1PutChar(12); printString("Streaming \0"); printCounter(cnt/60); UART1PutChar(58); printCounter(cnt%60); UART1PutChar(10); UART1PutChar(13); printString(" start \0"); printString(" stop \0"); once = 1; if(!counting) { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(148); } else { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(7); UART1PutChar(1); UART1PutChar(11); } }
F-8
ECE 477 Final Report Spring 2009
break;
//Volume Menu case 4: if(pb2) { pb2 = 0; if(volumestatus < 15) { UART1PutChar(216); SPIMPolPut(53); SPIMPolIsTransmitOver(); mSPIMPolGet(); SPIMPolPut(0); SPIMPolIsTransmitOver(); mSPIMPolGet(); volumestatus++; } } if(pb1) { pb1 = 0; if(volumestatus >= 1) { UART1PutChar(8); SPIMPolPut(69); SPIMPolIsTransmitOver(); mSPIMPolGet(); SPIMPolPut(0); SPIMPolIsTransmitOver(); mSPIMPolGet(); volumestatus--; } }
if(!once) { UART1PutChar(12); printString("Volume \0");
UART1PutChar(10); UART1PutChar(13); volumecounter = 0; while(volumecounter < volumestatus) { UART1PutChar(216); volumecounter++; } once = 1; } break;
//Effect Menu case 5: if(!firstCase) { UART1PutChar(12); printString("Effect");
F-9
ECE 477 Final Report Spring 2009
UART1PutChar(10); UART1PutChar(13); printString(" None Flange\0"); firstCase = 1; if(effect == 0) { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17); UART1PutChar(6); UART1PutChar(1); UART1PutChar(11); } else { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(6); UART1PutChar(1); UART1PutChar(148); }
}
if(pb2) { UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(11); UART1PutChar(17); UART1PutChar(6); UART1PutChar(1); UART1PutChar(148); effect = 1; SPIMPolPut(34); //Start flanging SPIMPolIsTransmitOver(); mSPIMPolGet(); //storeStatus = 0; pb2 = 0; } if(pb1) { SPIMPolPut(25); //Start streaming SPIMPolIsTransmitOver(); mSPIMPolGet(); UART1PutChar(17); UART1PutChar(0); UART1PutChar(1); UART1PutChar(148); UART1PutChar(17);
F-10
ECE 477 Final Report Spring 2009
UART1PutChar(6); UART1PutChar(1); UART1PutChar(11); pb1 = 0; effect = 0; } break; }
//LCDProcessEvents();
} // End of while(1)...} // End of main()...
/* Cases are toggled between by hitting one of the pushbuttons. The microcontroller scans the pushbuttons within one of the two timer interrupt service routines described below. If the pushbutton is hit, the ISR sets flag corresponding to that pushbutton. There are two timer interrupts in the microcontroller. The first is set to interrupt every 5ms and scan the 3 pushbuttons ALF has. The other timer interrupt is set to cause an interrupt every 1 second. It is used to increment the counter which is displayed when ALF is recording, streaming, or playing audio. */
//1 second timer interruptvoid __attribute__((__interrupt__)) _T1Interrupt( void ){ if(startuptimer == 0) { startuptimer = 1; } //Increment counter as needed depending on menu and display update on LCD if(menu == 0) { if(counting) { cnt++; //Increment 1 second counter UART1PutChar(17); UART1PutChar(12); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt%60); if(cnt/60 > 0) { UART1PutChar(17); UART1PutChar(9); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt/60); } } } else if(menu == 3) { if(counting) { cnt++;
F-11
ECE 477 Final Report Spring 2009
UART1PutChar(17); UART1PutChar(15); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt%60); if(cnt/60 > 0) { UART1PutChar(17); UART1PutChar(12); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt/60); } } } else if(menu == 1) { if(counting) { if(cnt > 0) { cnt--; } UART1PutChar(17); UART1PutChar(14); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt%60); if(cnt/60 > 0) { UART1PutChar(17); UART1PutChar(11); UART1PutChar(0); UART1PutChar(8); UART1PutChar(8); printCounter(cnt/60); } } } else if(menulast == 1 && counting) { cnt--; } else if(menulast == 3 && counting) { cnt++; } /* reset Timer 1 interrupt flag */ IFS0bits.T1IF = 0;}
//5ms timer interrupt to monitor pushbuttonsvoid __attribute__((__interrupt__)) _T2Interrupt( void ){ if(pb2prev != PORTBbits.RB12)
F-12
ECE 477 Final Report Spring 2009
{ pb2 = !PORTBbits.RB12; } if(pb1prev != PORTBbits.RB13) { pb1 = !PORTBbits.RB13; } if(pb3prev != PORTBbits.RB14) { pb3 = !PORTBbits.RB14; } pb2prev = PORTBbits.RB12; pb1prev = PORTBbits.RB13; pb3prev = PORTBbits.RB14; IFS0bits.T2IF = 0; }
F-13
ECE 477 Final Report Spring 2009
---lcd.c---/******************************************************************* * * LCD Driver for PIC24. *********************************************************************** * FileName: lcd.c * Dependencies: system.h, uart2.c * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * A simple LCD driver for LCDs interface through the PMP * * * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ross Fosler 08/13/04 ... * Anton Alkhimenok 10/18/05 added message copying to UART * Brant Ivey 3/14/06 Changed PMPEN register to PMAEN ********************************************************************/#include "system.h"
// Define a fast instruction execution time in terms of loop time// typically > 43us#define LCD_F_INSTR 10
// Define a slow instruction execution time in terms of loop time// typically > 1.35ms#define LCD_S_INSTR 150
// Define the startup time for the LCD in terms of loop time// typically > 30ms#define LCD_STARTUP 2000
F-14
ECE 477 Final Report Spring 2009
#define _LCD_IDLE(__cnt) _uLCDstate = 1; _uLCDloops = __cnt;#define _LCD_INIT(__cnt) _uLCDstate++; _uLCDloops = __cnt;
unsigned int _uLCDloops;unsigned char _uLCDstate;unsigned char _uLCDchar;
/********************************************************************* * Function: LCDProcessEvents * * Preconditions: None. * * Overview: This is a state mashine to issue commands and data to LCD. Must be * called periodically to make LCD message processing. * * Input: None. * * Output: None. * *********************************************************************/void printString(char * wordIn){ char input; //input = wordIn; while(*wordIn != '\0') { input = *wordIn; UART1PutChar(*wordIn); wordIn++; } return;}
F-15
ECE 477 Final Report Spring 2009
---spimpol.c---/************************************************************************* ** This implements a generic library functionality to support ** SPI Master for dsPIC/PIC24 family ** *************************************************************************** Company: Microchip Technology, Inc. ** ** Software License Agreement ** ** The software supplied herewith by Microchip Technology Incorporated ** (the "Company") for its PICmicro® Microcontroller is intended and ** supplied to you, the Company's customer, for use solely and ** exclusively on Microchip PICmicro Microcontroller products. The ** software is owned by the Company and/or its supplier, and is ** protected under applicable copyright laws. All rights are reserved. ** Any use in violation of the foregoing restrictions may subject the ** user to criminal sanctions under applicable laws, as well as to ** civil liability for the breach of the terms and conditions of this ** license. ** ** THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, ** WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED ** TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ** PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, ** IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR ** CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. ** ** Author Date Comment **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Alkhimenok Oct 26, 2005 .... *************************************************************************/#include "system.h"
/************************************************************************* Function: SPIMPolInit ** ** Preconditions: TRIS bits of SCK and SDO should be made output. ** TRIS bit of SDI should be made input. TRIS bit of Slave Chip Select ** pin (if any used) should be made output. Overview This function is ** used for initializing the SPI module. It initializes the module ** according to Application Maestro options. ** ** Input: Application Maestro options ** ** Output: None ** *************************************************************************/ //Initialize registersvoid SPIMPolInit(){ SPISTAT = 0; SPICON = (SPIM_PPRE|SPIM_SPRE); SPICONbits.MSTEN = 1; SPICON2 = 0; SPICONbits.MODE16 = SPIM_MODE16; // = 0 8 bits wide mode SPICONbits.CKE = 1;// SPIM_CKE; //0 SPICONbits.CKP = SPIM_CKP; //0
F-16
ECE 477 Final Report Spring 2009
SPICONbits.SMP = SPIM_SMP; //0 changed to 0 sample in middle of clock SPIINTENbits.SPIIE = 0;//set the interrupts SPIINTFLGbits.SPIIF = 0; SPISTATbits.SPIEN = 1;}
/************************************************************************* Function SPIMPolPut ** ** Preconditions: 'SPIMPolInit' should have been called. ** Overview: in non Blocking Option this function sends the byte ** over SPI bus and checks for Write Collision; in Blocking Option ** it waits for a free transmission buffer. ** ** Input: Data to be sent. ** ** Output: 'This function returns ‘0’ on proper initialization of ** transmission and ‘SPIM_STS_WRITE_COLLISION’ on occurrence of ** the Write Collision error. ** *************************************************************************/ unsigned SPIMPolPut(unsigned Data){#ifndef SPIM_BLOCKING_FUNCTION
if(SPISTATbits.SPITBF) return SPIM_STS_WRITE_COLLISION; SPIBUF = Data; return 0;
#else
// Wait for a data byte reception while(SPISTATbits.SPITBF); SPIBUF = Data; return 0;
#endif}
/************************************************************************* Function: SPIMPolIsTransmitOver ** ** Preconditions: ‘SPIMPolPut’ should have been called. ** Overview: in non Blocking Option this function checks whether ** the transmission of the byte is completed; in Blocking Option ** it waits till the transmission of the byte is completed. ** ** Input: None ** ** Output: in Blocking Option none and in non Blocking Option ** it returns: ’0’ - if the transmission is over, ** SPIM_STS_TRANSMIT_NOT_OVER - if the transmission is not yet over. ** *************************************************************************/unsigned SPIMPolIsTransmitOver(){#ifndef SPIM_BLOCKING_FUNCTION
F-17
ECE 477 Final Report Spring 2009
if(SPISTATbits.SPIRBF == 0) return SPIM_STS_TRANSMIT_NOT_OVER; return 0;
#else
// Wait for a data byte reception while(SPISTATbits.SPIRBF == 0); return 0;
#endif}
F-18
ECE 477 Final Report Spring 2009
---timer.c---/***************************************************************************** * * Timer * ***************************************************************************** * FileName: timer.c * Dependencies: system.h * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * Functions to setup timer and detect overflow * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ross Fosler 04/28/03 ... * *****************************************************************************/#include "system.h"
/********************************************************************* * Function: TimerInit * * PreCondition: None. * * Input: None. * * Output: None. * * Overview: Initializes Timer0 for use. * ********************************************************************/void printCounter(int count){ int tens;
F-19
ECE 477 Final Report Spring 2009
int ones; ones = count%10; tens = count/10; UART1PutChar(tens+48); UART1PutChar(ones+48);}
void TimerInit(void){
PR1 = 0xF424;
IPC0bits.T1IP = 1;T1CON = 0b1000000000100000;IFS0bits.T1IF = 0;
IEC0bits.T1IE = 1;
PR2 = 0x0138;
IPC1bits.T2IP = 1;T2CON = 0b1000000000100000;IFS0bits.T2IF = 0;
IEC0bits.T2IE = 1;/*T1CON = 0x00; //Stops the Timer1 and reset control reg.TMR1 = 0x00; //Clear contents of the timer registerPR1 = 0xFFFF; //Load the Period register with the value 0xFFFFIPC0bits.T1IP = 0x01; //Setup Timer1 interrupt for desired priority level// (This example assigns level 1 priority)IFS0bits.T1IF = 0; //Clear the Timer1 interrupt status flag //Enable Timer1 interruptsT1CONbits.TON = 1; //Start Timer1 with prescaler settings at 1:1 and*/return;
}
/********************************************************************* * Function: TimerIsOverflowEvent * * PreCondition: None. * * Input: None. * * Output: Status. * * Overview: Checks for an overflow event, returns TRUE if * an overflow occured. * * Note: This function should be checked at least twice * per overflow period. ********************************************************************/unsigned char TimerIsOverflowEvent(void){
if (IFS0bits.T1IF){
IFS0bits.T1IF = 0;return(1);
}
F-20
ECE 477 Final Report Spring 2009
---uart2.c---/***************************************************************************** * * UART Driver for PIC24. * ***************************************************************************** * FileName: uart2.c * Dependencies: system.h * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * A simple UART polled driver * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Anton Alkhimenok 10/18/05 ... * Brant Ivey 3/14/06 Added support for PIC24FJ64004 PIM *****************************************************************************/#include "system.h"
/***************************************************************************** * U2BRG register value and baudrate mistake calculation *****************************************************************************/#define BAUDRATEREG2 SYSCLK/32/BAUDRATE2-1
#if BAUDRATEREG2 > 255#error Cannot set up UART2 for the SYSCLK and BAUDRATE.\ Correct values in main.h and uart2.h files.#endif
#define BAUDRATE_MISTAKE 1000*(BAUDRATE2-SYSCLK/32/(BAUDRATEREG2+1))/BAUDRATE2#if (BAUDRATE_MISTAKE > 2)||(BAUDRATE_MISTAKE < -2)#error UART2 baudrate mistake is too big for the SYSCLK\ and BAUDRATE2. Correct values in uart2.c file.#endif
F-22
ECE 477 Final Report Spring 2009
/***************************************************************************** * Function: UART1Init * * Precondition: None. * * Overview: Setup UART2 module. * * Input: None. * * Output: None. * *****************************************************************************/void UART1Init(){ // Set directions of UART IOs
TRISBbits.TRISB0= 0;TRISBbits.TRISB1 = 1;U1BRG = BAUDRATEREG2;U1MODE = 0;U1STA = 0;U1MODEbits.UARTEN = 1;U1STAbits.UTXEN = 1;
// reset RX flag IFS0bits.U1RXIF = 0;}
/***************************************************************************** * Function: UART1PutChar * * Precondition: UART1Init must be called before. * * Overview: Wait for free UART transmission buffer and send a byte. * * Input: Byte to be sent. * * Output: None. * *****************************************************************************/void UART1PutChar(char Ch){ // wait for empty buffer while(U1STAbits.UTXBF == 1); U1TXREG = Ch;}
F-23
ECE 477 Final Report Spring 2009
---lcd.h---/***************************************************************************** * * LCD Driver for PIC24. * ***************************************************************************** * FileName: lcd.h * Dependencies: * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * A simple LCD driver for LCDs interface through the PMP * * * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ross Fosler 08/13/04 ... * Alkhimenok 10/28/05 added some comments *****************************************************************************/
// Display line length.#define LCD_DISPLAY_LEN 16
// Interface variables used by control macros.extern unsigned int _uLCDloops;extern unsigned char _uLCDchar;extern unsigned char _uLCDstate;
/***************************************************************************** * Function: LCDProcessEvents * * Preconditions: None. *
F-24
ECE 477 Final Report Spring 2009
* Overview: This is a state mashine to issue commands and data to LCD. Must be * called periodically to make LCD message processing. * * Input: None. * * Output: None. * *****************************************************************************/void printString(char * wordIn);void LCDProcessEvents(void);
/***************************************************************************** * Macro: mLCDIsBusy * * Preconditions: None. * * Overview: Query if the LCD is busy processing. * * Input: None. * * Output: Macro returns zero if LCD is not busy. * *****************************************************************************/#define mLCDIsBusy() _uLCDstate
/***************************************************************************** * Macro: mLCDInit * * Preconditions: None. * * Overview: Init the LCD. * * Input: None. * * Output: None. * *****************************************************************************/#define mLCDInit() _uLCDstate = 2;
/***************************************************************************** * Macro: mLCDPutChar * * Preconditions: Call of mLCDInit must be done. * * Overview: Put a character on the display. * * Input: Character. * * Output: None. * *****************************************************************************/#define mLCDPutChar(__lcd_char) _uLCDchar = __lcd_char; _uLCDstate = 3;
/***************************************************************************** * Macro: mLCDPutChar * * Preconditions: None. *
F-25
ECE 477 Final Report Spring 2009
* Overview: Send a generic command. * * Input: Command. * * Output: None. * *****************************************************************************/#define mLCDPutCmd(__lcd_cmd) _uLCDchar = __lcd_cmd; _uLCDstate = 6;
/***************************************************************************** * Macro: mLCDClear * * Preconditions: None. * * Overview: Clear the display. * * Input: None. * * Output: None. * *****************************************************************************/#define mLCDClear() _uLCDstate = 4;
/***************************************************************************** * Macro: mLCDHome * * Preconditions: None. * * Overview: Home the display. * * Input: None. * * Output: None. * *****************************************************************************/#define mLCDHome() _uLCDstate = 5; _uLCDchar = 0;
/***************************************************************************** * Macro: mLCDEMode * * Preconditions: None. * * Overview: Set the mode, dir and shift. * * Input: Command. * * Output: None. * *****************************************************************************/#define mLCDEMode(__lcd_cmd) _uLCDchar = __lcd_cmd | 0x04; _uLCDstate = 6;
/***************************************************************************** * Macro: mLCDCtl * * Preconditions: None. * * Overview: Set the display control, on/off, cursor. *
F-26
ECE 477 Final Report Spring 2009
* Input: Command. * * Output: None. * *****************************************************************************/#define mLCDCtl(__lcd_cmd) _uLCDchar = __lcd_cmd | 0x08; _uLCDstate = 6;
// #define mLCDShift(__lcd_cmd) _uLCDchar = __lcd_cmd | 0x10; _uLCDstate = 6;
/***************************************************************************** * Macro: mLCDFSet * * Preconditions: None. * * Overview: Set the interface. * * Input: Address. * * Output: None. * *****************************************************************************/#define mLCDFSet(__lcd_cmd) _uLCDchar = __lcd_cmd | 0x20; _uLCDstate = 6;
/***************************************************************************** * Macro: mLCDCDAddr * * Preconditions: None. * * Overview: Set the CGRAM address. * * Input: Address. * * Output: None. * *****************************************************************************/#define mLCDCDAddr(__lcd_addr) _uLCDchar = __lcd_addr | 0x40; _uLCDstate = 6;
/***************************************************************************** * Macro: mLCDAddr * * Preconditions: None. * * Overview: Set the DDRAM address. * * Input: Address. * * Output: None. * *****************************************************************************/#define mLCDAddr(__lcd_addr) _uLCDchar = __lcd_addr | 0x80; _uLCDstate = 6;
/***************************************************************************** * EOF *****************************************************************************/
F-27
ECE 477 Final Report Spring 2009
---spimpol.h---/************************************************************************* ** This implements a generic library functionality to support SPI Master ** for dsPIC/PIC24 family ** *************************************************************************** Company: Microchip Technology, Inc. ** ** Software License Agreement ** ** The software supplied herewith by Microchip Technology Incorporated ** (the "Company") for its PICmicro® Microcontroller is intended and ** supplied to you, the Company's customer, for use solely and ** exclusively on Microchip PICmicro Microcontroller products. The ** software is owned by the Company and/or its supplier, and is ** protected under applicable copyright laws. All rights are reserved. ** Any use in violation of the foregoing restrictions may subject the ** user to criminal sanctions under applicable laws, as well as to ** civil liability for the breach of the terms and conditions of this ** license. ** ** THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, ** WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED ** TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A ** PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, ** IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR ** CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. ** ** Author Date Comment **~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~** Alkhimenok Oct 26, 2005 .... *************************************************************************/// USE ONY ONCE // #ifndef _spimpol_h_#define _spimpol_h_
#ifndef BOARD_VERSION4#define SPIM_SPI1#else#define SPIM_SPI2#endif
#define SPIM_PIC24#define SPIM_BLOCKING_FUNCTION#define SPIM_MODE16 0#define SPIM_SMP 0#define SPIM_CKE 0#define SPIM_CKP 0#define SPIM_PPRE (unsigned)0#define SPIM_SPRE (unsigned)0
/************************************************************************* ** This section defines names of control registers of SPI Module. ** Names depends of processor type and module number. ** *
F-28
ECE 477 Final Report Spring 2009
************************************************************************/ #define SPIBUF SPI1BUF #define SPISTAT SPI1STAT #define SPIBUFbits SPI1BUFbits #define SPISTATbits SPI1STATbits #define SPIINTEN IEC0 #define SPIINTFLG IFS0 #define SPIINTENbits IEC0bits #define SPIINTFLGbits IFS0bits #define SPIIF SPI1IF #define SPIIE SPI1IE #define SPICON SPI1CON1 #define SPICONbits SPI1CON1bits #define SPICON2 SPI1CON2 #define SPICON2bits SPI1CON2bits
/************************************************************************* Error and Status Flags ** SPIM_STS_WRITE_COLLISION indicates that, Write collision has occurred ** while trying to transmit the byte. ** * * SPIM_STS_TRANSMIT_NOT_OVER indicates that, the transmission is ** not yet over. This is to be checked only when non Blocking ** option is opted. ** * * SPIM_STS_DATA_NOT_READY indicates that reception SPI buffer is empty ** and there's no data avalable yet. * * * ************************************************************************/#define SPIM_STS_WRITE_COLLISION 1#define SPIM_STS_TRANSMIT_NOT_OVER 2 #define SPIM_STS_DATA_NOT_READY 3
/************************************************************************* Macro: mSPIMPolGet ** ** PreCondition: 'SPIMPolIsTransmitOver' should return a '0'. ** ** Overview: This macro reads a data received ** ** Input: None ** ** Output: Data received ** *************************************************************************/#define mSPIMPolGet() SPIBUF
/************************************************************************* Function: SPIMPolInit ** ** Preconditions: TRIS bits of SCK and SDO should be made output. ** TRIS bit of SDI should be made input. TRIS bit of Slave Chip Select ** pin (if any used) should be made output. Overview This function is ** used for initializing the SPI module. It initializes the module ** according to Application Maestro options. ** ** Input: Application Maestro options ** *
F-29
ECE 477 Final Report Spring 2009
* Output: None ** *************************************************************************/ extern void SPIMPolInit();/************************************************************************* Function SPIMPolPut ** ** Preconditions: 'SPIMPolInit' should have been called. ** Overview: in non Blocking Option this function sends the byte ** over SPI bus and checks for Write Collision; in Blocking Option ** it waits for a free transmission buffer. ** ** Input: Data to be sent. ** ** Output: 'This function returns ‘0’ on proper initialization of ** transmission and ‘SPIM_STS_WRITE_COLLISION’ on occurrence of ** the Write Collision error. ** *************************************************************************/ extern unsigned SPIMPolPut(unsigned Data);/************************************************************************* Function: SPIMPolIsTransmitOver ** ** Preconditions: ‘SPIMPolPut’ should have been called. ** Overview: in non Blocking Option this function checks whether ** the transmission of the byte is completed; in Blocking Option ** it waits till the transmission of the byte is completed. ** ** Input: None ** ** Output: in Blocking Option none and in non Blocking Option ** it returns: ’0’ - if the transmission is over, ** SPIM_STS_TRANSMIT_NOT_OVER - if the transmission is not yet over. ** *************************************************************************/ extern unsigned SPIMPolIsTransmitOver();
#endif
F-30
ECE 477 Final Report Spring 2009
---timer.h---/***************************************************************************** * * Timer * ***************************************************************************** * FileName: timer.h * Dependencies: * Processor: * Compiler: * Linker: * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * This is a simple timer function used to provide quant for state machines * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Ross Fosler 04/28/03 ... * *****************************************************************************/
/********************************************************************* * Function: TimerInit * * PreCondition: None. * * Input: None. * * Output: None. * * Overview: Initializes Timer0 for use. * ********************************************************************/void printCounter(int count);extern void TimerInit(void);
F-31
ECE 477 Final Report Spring 2009
/********************************************************************* * Function: TimerIsOverflowEvent * * PreCondition: None. * * Input: None. * * Output: Status. * * Overview: Checks for an overflow event, returns TRUE if * an overflow occured. * * Note: This function should be checked at least twice * per overflow period. ********************************************************************/extern unsigned char TimerIsOverflowEvent(void);
/********************************************************************* * EOF ********************************************************************/
F-32
ECE 477 Final Report Spring 2009
---uart2.h---/***************************************************************************** * * UART Driver for PIC24. * Modified for PIC24FJ64GA004 family with PPS. * ***************************************************************************** * FileName: uart2.c * Dependencies: system.h * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * A simple UART polled driver * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Anton Alkhimenok 10/18/05 ... * Brant Ivey 3/14/06 Modified for PIC24FJ64GA004 family with PPS. *****************************************************************************/
/***************************************************************************** * DEFINITIONS *****************************************************************************/// Baudrate#define BAUDRATE2 19200
// UART IOs/*#ifdef __PIC24FJ64GA004__#define UART2_TX_TRIS PPS_UART2_TX_TRIS#define UART2_RX_TRIS PPS_UART2_RX_TRIS#else#define UART2_TX_TRIS TRISFbits.TRISF5#define UART2_RX_TRIS TRISFbits.TRISF4#endif*/
F-33
ECE 477 Final Report Spring 2009
/***************************************************************************** * Function: UART1Init * * Precondition: None. * * Overview: Setup UART1 module. * * Input: None. * * Output: None. * *****************************************************************************/extern void UART1Init();
/***************************************************************************** * Function: UART1PutChar * * Precondition: UART1Init must be called before. * * Overview: Wait for free UART transmission buffer and send a byte. * * Input: Byte to be sent. * * Output: None. * *****************************************************************************/extern void UART1PutChar(char Ch);
F-34
ECE 477 Final Report Spring 2009
---system.h---/***************************************************************************** * System * Modified for PIC24FJ64GA004 family with PPS. ***************************************************************************** * FileName: system.h * Dependencies: * Processor: PIC24 * Compiler: MPLAB C30 * Linker: MPLAB LINK30 * Company: Microchip Technology Incorporated * * Software License Agreement * * The software supplied herewith by Microchip Technology Incorporated * (the "Company") is intended and supplied to you, the Company's * customer, for use solely and exclusively with products manufactured * by the Company. * * The software is owned by the Company and/or its supplier, and is * protected under applicable copyright laws. All rights are reserved. * Any use in violation of the foregoing restrictions may subject the * user to criminal sanctions under applicable laws, as well as to * civil liability for the breach of the terms and conditions of this * license. * * THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES, * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT, * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * * * The file assembles all header files and * contains shared information for all modules * * Author Date Comment *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Anton Alkhimenok 10/21/05 ... * Brant Ivey 3/14/06 Modified for PIC24FJ64GA004 family with PPS. *****************************************************************************/
// External oscillator frequency#define SYSCLK 8000000
//Comment the line for 3rd board version #define BOARD_VERSION4
//Uncomment if PIC24F part is installed directly on board//#define PIM_SWAP
/*#ifdef __PIC24FJ64GA004__ //Defined by MPLAB when using 24FJ64GA004 device
#include "iomapping.h"#else
#define AN_VOLT_PIN AD1PCFGbits.PCFG5 //voltage input on AN5#define ADC_VOLT_CHAN 5
F-35
ECE 477 Final Report Spring 2009
#define AN_TEMP_PIN AD1PCFGbits.PCFG4 //temp input on AN4#define ADC_TEMP_CHAN 4
#endif*/#include <p24fxxxx.h>#include "timer.h"#include "uart2.h"#include "lcd.h"#include "spimpol.h"
/***************************************************************************** * EOF *****************************************************************************/
F-36
ECE 477 Final Report Spring 2009
FPGA Code
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--This is the top level entity and does all the port mapping of the other components. --The internal signals that also determine what audio data is sent to the CODEC are --also defined.
ENTITY ALF ISPORT(
CLOCK : in std_logic;---- SPI Signals
PIC_SCLK : in std_logic;PIC_MOSI : in std_logic;PIC_MISO : out std_logic;
-- SDRAM DRAM_ADDR : out std_logic_vector(11 downto 0);DRAM_BA_0 : out std_logic;DRAM_BA_1 : out std_logic;DRAM_CAS_N : out std_logic;DRAM_CKE : out std_logic;DRAM_CLK : out std_logic;DRAM_CS_N : out std_logic;DRAM_DQ : inout std_logic_vector(15 downto 0);DRAM_LDQM : out std_logic;DRAM_UDQM : out std_logic;DRAM_RAS_N : out std_logic;DRAM_WE_N : out std_logic;
---- AudioAUD_BCLK : in std_logic;AUD_ADCLRCK : in std_logic;AUD_DACLRCK : in std_logic;AUD_ADCDAT : in std_logic;AUD_DACDAT : out std_logic;AUD_XCK : out std_logic;I2C_SCLK : out std_logic;I2C_SDAT : inout std_logic;GPIO : inout std_logic_vector(9 downto 0));
end ALF;
architecture structural of ALF is signal nRST, igotData : std_logic;signal Audio_in, Audio_out, Audio_CODEC, Audio_Recorded : std_logic_vector(15
downto 0);signal iData: std_logic_vector(15 downto 0);signal iDACDAT2, iDACDAT, iXCK : std_logic;signal iDATA_TO_SEND : std_logic_vector(7 downto 0);signal iDATA_RECEIVED : std_logic_vector(7 downto 0);signal itx_full : std_logic;signal ibaud_tick : std_logic;signal itx_data : std_logic_vector(7 downto 0);signal itx_done_tick, ireadData, ireadData2 : std_logic;signal iq : std_logic_vector(3 downto 0);signal iLEDG : std_logic_vector(7 downto 0);signal iLEDR : std_logic_vector(15 downto 0);
F-37
ECE 477 Final Report Spring 2009
signal iPIC_MISO : std_logic;signal iPIC_MOSI : std_logic;signal icommand : std_logic_vector(7 downto 0);signal iRecord, iPlayback, idone, iFlange : std_logic;signal datasbeenread, Stream, iGetNewData, newData, datasbeenflanged : std_logic;signal CLOCK_50, dll_locked : std_logic;signal iaddress_f : std_logic_vector(12 downto 0);signal iwren_f : std_logic;signal idata_f, iq_f, idata2 : std_logic_vector(15 downto 0);signal useSendRecorded, soundReset, iSoundReset : std_logic;signal ivolume, newvolume : std_logic_vector(1 downto 0); component CLOCK100_to_50 is
port (areset : IN STD_LOGIC;inclk0 : IN STD_LOGIC;c0 : OUT STD_LOGIC;locked : OUT STD_LOGIC );
end component;
component flange isport(
clk : in std_logic;nrst : in std_logic;din_ready : in std_logic;din : in std_logic_vector(15 downto 0);dout_ready : in std_logic;dout : out std_logic_vector(15 downto 0);addr_ram : out std_logic_vector(12 downto 0);wren_ram : out std_logic;data_ram : out std_logic_vector(15 downto 0);q_ram : in std_logic_vector(15 downto 0);datasbeenflanged : out std_logic);
end component;
component ram_buffer isport(
address : IN STD_LOGIC_VECTOR (12 DOWNTO 0);clock : IN STD_LOGIC ;data : IN STD_LOGIC_VECTOR (15 DOWNTO 0);wren : IN STD_LOGIC ;q : OUT STD_LOGIC_VECTOR (15 DOWNTO 0)
);end component;
component Sound isport (
CLK : in std_logic;nRST : in std_logic;VolumeReset : in std_logic;AUD_ADCLRC : in std_logic;volume : in std_logic_vector(1 downto 0);I2C_SDAT : inout std_logic;AUD_XCK : out std_logic;I2C_SCLK_2 : out std_logic
);
F-38
ECE 477 Final Report Spring 2009
end component;
component getData ISPORT(
BCLK : in std_logic;ADCLRC : in std_logic;ADCDAT : in std_logic;nRST : in std_logic;DATA : out std_logic_vector(15 downto 0);gotData : out std_logic
);end component;
component sendData isPORT(
BCLK : in std_logic;DACLRC : in std_logic;iDATA : in std_logic_vector(15 downto 0);nRST : in std_logic;Stream : in std_logic;DACDAT : out std_logic;readData : out std_logic
);end component;
component sendRecordedAudio isPort (
BCLK : in std_logic;DACLRC : in std_logic;iDATA : in std_logic_vector(15 downto 0);nRST : in std_logic;DACDAT : out std_logic;newData : in std_logic;playRecorded : in std_logic;GetNewData : out std_logic
);end component;
component sdram isport (
CLOCK_50 : in std_logic;nRST : in std_logic;DATA : in std_logic_vector(15 downto 0);gotDATA : in std_logic;readData : in std_logic;RecordAudio : in std_logic;StartPlayback : in std_logic;DRAM_ADDR : out std_logic_vector(11 downto 0);DRAM_BA_0 : out std_logic;DRAM_BA_1 : out std_logic;DRAM_CAS_N : out std_logic;DRAM_CKE : out std_logic;DRAM_CLK : out std_logic;DRAM_CS_N : out std_logic;DRAM_DQ : inout std_logic_vector(15 downto 0);DRAM_LDQM : out std_logic;DRAM_UDQM : out std_logic;DRAM_RAS_N : out std_logic;
F-39
ECE 477 Final Report Spring 2009
DRAM_WE_N : out std_logic;Audio_out : out std_logic_vector(15 downto 0);done : out std_logic;Datasread : out std_logic
);end component;
component SPI_slave isport (
CLK : in std_logic;nRST : in std_logic;SCK : in std_logic;SSEL : in std_logic;MOSI : in std_logic;DATA_TO_SEND : in std_logic_vector(7 downto 0);MISO : out std_logic;DATA_RECEIVED : out std_logic_vector(7 downto 0)
);end component;
component itrptSPI isport (
clk : in std_logic;nRST : in std_logic;DATA_in : in std_logic_vector(7 downto 0);DATA_out : out std_logic_vector(7 downto 0);command : out std_logic_vector(7 downto 0);volume : out std_logic_vector(1 downto 0);SoundReset : out std_logic);
end component;
begin
PLL : CLOCK100_to_50port map( areset => (not nRST), inclk0 => CLOCK, c0 => CLOCK_50, locked => dll_locked ); U_0 : Soundport map(
CLK => CLOCK_50,nRST => nRST,VolumeReset => SoundReset,volume => ivolume,AUD_ADCLRC => AUD_ADCLRCK,I2C_SDAT=> I2C_SDAT,AUD_XCK => iXCK,I2C_SCLK_2 => I2C_SCLK
);
U_1 : getDataport map (
BCLK => AUD_BCLK,ADCLRC => AUD_ADCLRCK,ADCDAT => AUD_ADCDAT,
F-40
ECE 477 Final Report Spring 2009
nRST => nRST,DATA => Audio_in,gotData => igotData
);
U_2 : sendDataport map (
BCLK => AUD_BCLK,DACLRC => AUD_DACLRCK,iDATA => Audio_CODEC,Stream => Stream,nRST => nRST,DACDAT => iDACDAT,readData => ireadData
);
U_3 : sdramport map(
CLOCK_50 => CLOCK_50,nRST => nRST,DATA => Audio_in,gotData => igotData,RecordAudio => iRecord,StartPlayback => iPlayback,DRAM_ADDR => DRAM_ADDR,DRAM_BA_0 => DRAM_BA_0,DRAM_BA_1 => DRAM_BA_1,DRAM_CAS_N => DRAM_CAS_N,DRAM_CKE => DRAM_CKE,DRAM_CLK => DRAM_CLK,DRAM_CS_N => DRAM_CS_N,DRAM_DQ => DRAM_DQ,DRAM_LDQM => DRAM_LDQM,DRAM_UDQM => DRAM_UDQM,DRAM_RAS_N => DRAM_RAS_N,DRAM_WE_N => DRAM_WE_N,Audio_out => Audio_out,readData => iGetNewData,done => idone,Datasread => Datasbeenread
);
U_4 : SPI_slaveport map(
CLK => CLOCK_50,nRST => nRST,SCK => PIC_SCLK,SSEL => GPIO(0),MOSI => iPIC_MOSI,DATA_TO_SEND => iDATA_TO_SEND,MISO => iPIC_MISO,DATA_RECEIVED => iDATA_RECEIVED
);
U_5 : itrptSPIport map(
CLK => CLOCK_50,nRST => nRST, DATA_in => iDATA_RECEIVED,
F-41
ECE 477 Final Report Spring 2009
DATA_out => iDATA_TO_SEND,command => icommand,volume => ivolume,SoundReset => iSoundReset
);
U_6 : sendRecordedAudioport map (
BCLK => AUD_BCLK,DACLRC => AUD_DACLRCK,iDATA => Audio_Recorded,nRST => nRST,DACDAT => iDACDAT2,newData => newData,playRecorded => useSendRecorded,GetNewData => iGetNewData
);
U_7 : flangeport map(
clk => clock_50,nrst => nRST,din_ready => igotData,din => Audio_in,dout_ready => iGetNewData,dout => idata2,addr_ram => iaddress_f,wren_ram => iwren_f,data_ram => idata_f,q_ram => iq_f,datasbeenflanged => datasbeenflanged
);
U_8 : ram_bufferport map(
address => iaddress_f,clock => CLOCK_50,data => idata_f,wren => iwren_f,q => iq_f
);
with icommand selectAudio_CODEC <= Audio_in when x"19",
Audio_out when x"05", x"0000" when others;
with icommand select Audio_Recorded <= idata2 when x"22",
Audio_out when x"0F", x"0000" when others;
with icommand select AUD_DACDAT <= iDACDAT when x"19",
iDACDAT when x"05", iDACDAT2 when x"0F", iDACDAT2 when x"22", '0' when others;
F-42
ECE 477 Final Report Spring 2009
--When volume needs to change, sound needs a reset; SoundReset <= '1' when (iSoundReset='1' and nRST = '1') else '0';
Stream <= '1' when (icommand = x"19") else '0';iRecord <= '1' when (icommand = x"05") else '0';iPlayback <= '1' when (icommand = x"0F") else '0';iFlange <= '1' when (icommand = x"22") else '0';
nRST <= GPIO(1);AUD_XCK <= iXCK;PIC_MISO <= iPIC_MISO;iPIC_MOSI <= PIC_MOSI;newData <= Datasbeenread or Datasbeenflanged;useSendRecorded <= iPlayback or iFlange;
GPIO(3) <= Audio_Recorded(0);GPIO(4) <= iGetNewData;GPIO(5) <= soundReset;
end structural;
F-43
ECE 477 Final Report Spring 2009
// --------------------------------------------------------------------// Copyright (c) 2005 by Terasic Technologies Inc. // --------------------------------------------------------------------//// Permission://// Terasic grants permission to use and modify this code for use// in synthesis for all Terasic Development Boards and Altrea Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited.//// Disclaimer://// This VHDL or Verilog source code is intended as a design reference// which illustrates how these types of functions can be implemented.// It is the user's responsibility to verify their design for// consistency and functionality through the use of formal// verification methods. Terasic provides no warranty regarding the use // or functionality of this code.//// --------------------------------------------------------------------// // Terasic Technologies Inc// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,// HsinChu County, Taiwan// 302//// web: http://www.terasic.com/// email: [email protected]//// --------------------------------------------------------------------//// Major Functions: I2C output data//// --------------------------------------------------------------------//// Revision History :// --------------------------------------------------------------------// Ver :| Author :| Mod. Date :| Changes Made:// V1.0 :| Joe Yang :| 05/07/10 :| Initial Revision// --------------------------------------------------------------------// This component creates the signal that will be the clock for the I2C component. It //also determines what data will be sent to the CODEC for configuration. When the user //requests to change the volume, this is the component that does it by changing the //value in the register. It was modified from an Altera tutorial to fit our needs. //This component is fully implemented.
`define rom_size 6'd9
module CLOCK_500 (CLOCK,CLOCK_500,DATA,END1,RESET,volume,GO,
F-44
ECE 477 Final Report Spring 2009
CLOCK_2);
input CLOCK;input END1;input RESET;input [1:0]volume;output CLOCK_500;output [23:0]DATA;output GO;output CLOCK_2;
reg [10:0]COUNTER_500;
wire CLOCK_500=COUNTER_500[9];wire CLOCK_2=COUNTER_500[1];
reg [15:0]ROM[`rom_size:0];reg [15:0]DATA_A;reg [5:0]address;wire [23:0]DATA={8'h34,DATA_A};
wire GO =((address <= `rom_size) && (END1==1))? COUNTER_500[10]:1'b1;always @(negedge RESET or posedge END1) begin
if (!RESET) address=0;else if (address <= `rom_size) address=address+6'b1;
end
reg [4:0]vol;
initial beginvol = 5'b01110;
end
always @(posedge RESET) beginif (volume==2'b10 & vol!=5'b00000)
vol=vol-5'b10;else if (volume==2'b01 & vol!=5'b11011)
vol=vol+5'b10;end
always @(posedge END1) begin// ROM[0]= 16'h1e00;
ROM[0]= 16'h0c00; //power downROM[1]= 16'h0e42; // BCLK, enable Master, right Channel DAC Data Right,
MSB available on 1st BCLK, 16 bit input data length, I2S format, MSB-first left-1 justified
ROM[2]= 16'h0812; //-6dB, disable sidetone, select DAC, disable bypass, line input select to ADc, disable mute, disable boost
ROM[3]= 16'h1000; //CLOCKOUT is core clock, core clock is mclk, ADC/DAC sample rate control, 256fs (oversampling rate), normal mode
ROM[4]= {8'h00, 3'b0, vol[4:0]}; //disable simultaneous load, disable mute, 0dB
ROM[5]= {8'h02, 3'b0, vol[4:0]}; //disable simultaneous load, disable mute, 0dB
F-45
ECE 477 Final Report Spring 2009
ROM[6]= {8'h04, 1'b0, 7'b1010111}; //disable simultaneous load, disable left channel zero cross detect,
ROM[7]= {8'h06, 1'b0, 7'b1010111}; //sound volROM[8]= 16'h0A00; //disable soft mute//ROM[4]= 16'h1e00; //resetROM[`rom_size]= 16'h1201;//activeDATA_A=ROM[address];
end
always @(posedge CLOCK ) beginCOUNTER_500=COUNTER_500+11'b1;
end
endmodule
F-46
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
-- this module uses a memory buffer (from the Altera RAM megafunction) and-- creates a circular buffer so that delayed input (with gain) can be-- added to the current input and sent to SendRecordedAudio (which takes -- care of sending audio to the CODEC). Flange is essentially an echo effect.
ENTITY flange ISPORT(
clk : in std_logic;nrst : in std_logic;din_ready : in std_logic;
-- signal from getData that data_in is readydin : in std_logic_vector(15 downto 0);
-- data_in from getDatadout_ready : in std_logic;
-- signal from SendRecordedAudio that data_out can be sentdout : out std_logic_vector(15 downto 0);
-- data_out going to SendRecordedAudioaddr_ram : out std_logic_vector(12 downto 0);
-- address for memory bufferwren_ram : out std_logic; -- read-write enable for memory bufferdata_ram : out std_logic_vector(15 downto 0);
-- data_in to memory bufferq_ram : in std_logic_vector(15 downto 0);
-- data_out from memory bufferdatasbeenflanged : out std_logic
-- signal to SendRecordedAudio that data_out is ready to be sent);
end flange;
architecture behavioral of flange is signal addr, nextaddr : std_logic_vector(12 downto 0);signal memin, nextmemin : std_logic_vector(15 downto 0); -- memin is to make sure that the input to the memory buffer --is stable and not changing when getData changes signal memout, nextmemout : std_logic_vector(15 downto 0); -- memout is to make sure that the output from the memory --buffer does not affect the entity data out (addr_ram is always active)signal idatasbeenflanged, nextdatasbeenflanged : std_logic;type statetype is (idle, getdata, prepareaddr, preparewrite1);signal state, nextstate : statetype;signal Q1, Q2: std_logic; --edge of "din ready" signalsignal Q3, Q4: std_logic; --edge of "dout ready" signal
beginStateReg : process (clk, nrst)begin
if (nrst = '0') thenaddr <= (others => '0');Q1 <= '0';Q2 <= '0';Q3 <= '0';Q4 <= '0';state <= IDLE;idatasbeenflanged <= '0';
F-47
ECE 477 Final Report Spring 2009
elsif rising_edge(CLK) thenstate <= nextstate;addr <= nextaddr;memin <= nextmemin;memout <= nextmemout;idatasbeenflanged <= nextdatasbeenflanged;Q1 <= din_ready;Q2 <= Q1;Q3 <= dout_ready;Q4 <= Q3;
end if;end process;
StateMachine: process(state, memin, memout, addr, idatasbeenflanged, din, q_ram, Q1, Q2, Q3, Q4)
beginnextaddr <= addr;nextmemin <= memin;nextmemout <= memout;wren_ram <= '0';nextdatasbeenflanged <= idatasbeenflanged;
case state is
when IDLE =>if Q1='0' and Q2='1' then
nextstate <= GETDATA;elsif Q3='0' and Q4='1' then
nextstate <= PREPAREWRITE1;elsif Q3='1' and Q4='0' then
nextdatasbeenflanged <= '0';nextstate <= state;
elsenextstate <= state;
end if;
when GETDATA => nextmemin <= din;wren_ram <= '1';nextstate <= PREPAREADDR;
when PREPAREADDR =>
wren_ram <= '0'; -- read enableif (addr = "1111111111111") then -- fill up the memory buffer
nextaddr <= (others => '0');else
nextaddr <= addr + 1;end if;nextstate <= IDLE;
when PREPAREWRITE1 =>nextmemout <= q_ram(15 downto 0) + memin; -- add delayed input to
inputnextdatasbeenflanged <= '1'; -- now data is ready to send to
SendRecordedAudionextstate <= IDLE;
end case;end process;
F-48
ECE 477 Final Report Spring 2009
addr_ram <= addr;datasbeenflanged <= idatasbeenflanged;data_ram <= memin;dout <= memout;
end behavioral;
F-49
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--This component is what captures the data from the CODEC. When there’s a transition --on the ADC clock, a shift register is used to capture the 16 bits from the CODEC. --Once a full 16 bits has been read, a flag is asserted to let any components --connected to it that new data has been read. This component is fully implemented. ENTITY getData IS
PORT(BCLK : in std_logic;ADCLRC : in std_logic;ADCDAT : in std_logic;nRST : in std_logic;DATA : out std_logic_vector(15 downto 0);gotData : out std_logic
-- rising : out std_logic;-- falling : out std_logic;-- prev : out std_logic;-- LEDR : out std_logic_vector(6 downto 0)
);end getData;
architecture behavioral of getData is signal counter, nextcounter : std_logic_vector(3 downto 0);type statetype is (init, idle, getLeft, getRight, donothingRight, donothingLeft);signal state, nextstate : statetype;signal SendData, nextSendData : std_logic_vector(15 downto 0);signal nextData, iData : std_logic_vector(15 downto 0);signal Q2, Q1, ifalling, irising : std_logic;signal prevADCLRC, nextADCLRC : std_logic;--signal nextLEDs, LEDs : std_logic_vector(6 downto 0);
beginStateReg : process (bclk, nrst)begin
if (nrst = '0') thencounter <= (others => '0');state <= INIT;SendData <= (others => '0');Q2 <= '0';Q1 <= '0';
-- prevADCLRC <= '0';iData <= (others => '0');
-- LEDs <= (others => '0');elsif falling_edge(BCLK) then
state <= nextstate;counter <= nextcounter;SendData <= nextSendData;iData <= nextData;
-- prevADCLRC <= nextADCLRC;Q1 <= ADCLRC;Q2 <= Q1;
-- Leds <= nextLEDs;end if;
end process;
F-50
ECE 477 Final Report Spring 2009
StateMachine: process(Q2, Q1, iData, ifalling, irising, state, counter, ADCDAT, ADCLRC, SendData) --risingEdgeADC, fallingEdgeADC
beginnextcounter <= counter;nextSendData <= SendData;nextData <= iData;gotData <= '0';case state is
when INIT => if Q1='0' and Q2='1' then
nextSendData <= sendData(14 downto 0) & ADCDAT;nextstate <= getLeft;--getLeft;
elsenextstate <= state;
end if;
when donothingLeft => -- nextLEDs(4) <= '1';
nextstate <= getLeft;when donothingRight =>
-- nextLEDs(5) <= '1';nextstate <= getRight;
when IDLE =>-- nextLEDs(1) <= '1';
nextsendData <= (others => '0');if Q1='0' and Q2='1' then
nextSendData <= sendData(14 downto 0) & ADCDAT;nextstate <= getLeft;
elsif Q1='1' and Q2='0' thennextSendData <= sendData(14 downto 0) & ADCDAT;nextstate <= getRight;
elsenextstate <= IDLE;
end if;
when getLeft => -- falling <= '1';-- nextLEDs(2) <= '1';
if (counter = x"E") thennextData <= sendData(14 downto 0) & ADCDAT;nextcounter <= x"0";nextstate <= IDLE;gotData <='1';
elsegotData <= '0';nextSendData <= sendData(14 downto 0) & ADCDAT;nextcounter <= counter + 1;nextstate <= state;
end if;
when getRight =>-- rising <= '1';-- nextLEDs(3) <= '1';
if (counter = x"E") thennextData <= sendData(14 downto 0) & ADCDAT;nextcounter <= x"0";nextstate <= IDLE;
F-51
ECE 477 Final Report Spring 2009
gotData <='1';else
gotData <='0';nextSendData <= sendData(14 downto 0) & ADCDAT;nextcounter <= counter + 1;nextstate <= state;
end if;
when others =>-- nextLEDs(6) <= '1';
nextstate <= IDLE;
end case;end process;
-- falling <= fallingedgeADC;-- rising <= risingedgeADC;-- falling <= '1' when ADCLRC = '0' and prevADCLRC = '1' else '0';-- rising <= '1' when ADCLRC = '1' and prevADCLRC = '0' else '0';-- prev <= prevADCLRC;
Data <= iDATA;-- LEDR <= LEDs;end behavioral;
F-52
ECE 477 Final Report Spring 2009
// --------------------------------------------------------------------// Copyright (c) 2005 by Terasic Technologies Inc. // --------------------------------------------------------------------//// Permission://// Terasic grants permission to use and modify this code for use// in synthesis for all Terasic Development Boards and Altrea Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited.//// Disclaimer://// This VHDL or Verilog source code is intended as a design reference// which illustrates how these types of functions can be implemented.// It is the user's responsibility to verify their design for// consistency and functionality through the use of formal// verification methods. Terasic provides no warranty regarding the use // or functionality of this code.//// --------------------------------------------------------------------// // Terasic Technologies Inc// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,// HsinChu County, Taiwan// 302//// web: http://www.terasic.com/// email: [email protected]//// --------------------------------------------------------------------//// Major Functions:i2c controller//// --------------------------------------------------------------------//// Revision History :// --------------------------------------------------------------------// Ver :| Author :| Mod. Date :| Changes Made:// V1.0 :| Joe Yang :| 05/07/10 :| Initial Revision// --------------------------------------------------------------------// This component takes the data from CLOCK_500 and sends it out via the I2C protocol //to the codec. It is a very lightly modified version of one found in an Altera //tutorial. This component is fully implemented.
module i2c (CLOCK,I2C_SCLK,//I2C CLOCK
I2C_SDAT,//I2C DATAI2C_DATA,//DATA:[SLAVE_ADDR,SUB_ADDR,DATA]GO, //GO transforEND1, //END transfor W_R, //W_RACK, //ACKRESET
);input CLOCK;
F-53
ECE 477 Final Report Spring 2009
input [23:0]I2C_DATA;input GO;input RESET;input W_R;
inout I2C_SDAT;output I2C_SCLK;output END1;output ACK;
//TEST// output [5:0] SD_COUNTER;// output SDO;
reg SDO;reg SCLK;reg END1;reg [23:0]SD;reg [5:0]SD_COUNTER;
wire I2C_SCLK=SCLK | ( ((SD_COUNTER >= 4) & (SD_COUNTER <=30))? ~CLOCK :1'b0 );wire I2C_SDAT=SDO;//?1'bz:0 ;
reg ACK1,ACK2,ACK3;wire ACK=ACK1 | ACK2 |ACK3;
//--I2C COUNTERalways @(negedge RESET or posedge CLOCK ) beginif (!RESET) SD_COUNTER=6'b111111;else beginif (GO==0)
SD_COUNTER=0;else if (SD_COUNTER < 6'b111111) SD_COUNTER=SD_COUNTER+6'b1;
endend//----
always @(negedge RESET or posedge CLOCK ) beginif (!RESET) begin SCLK=1;SDO=1; ACK1=0;ACK2=0;ACK3=0; END1=1; endelsecase (SD_COUNTER)
6'd0 : begin ACK1=0 ;ACK2=0 ;ACK3=0 ; END1=0; SDO=1; SCLK=1;end//start6'd1 : begin SD=I2C_DATA;SDO=0;end6'd2 : SCLK=0;//SLAVE ADDR6'd3 : SDO=SD[23];6'd4 : SDO=SD[22];6'd5 : SDO=SD[21];6'd6 : SDO=SD[20];6'd7 : SDO=SD[19];6'd8 : SDO=SD[18];6'd9 : SDO=SD[17];6'd10 : SDO=SD[16];6'd11 : SDO=1'b1;//ACK
//SUB ADDR
F-54
ECE 477 Final Report Spring 2009
6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end6'd13 : SDO=SD[14];6'd14 : SDO=SD[13];6'd15 : SDO=SD[12];6'd16 : SDO=SD[11];6'd17 : SDO=SD[10];6'd18 : SDO=SD[9];6'd19 : SDO=SD[8];6'd20 : SDO=1'b1;//ACK
//DATA6'd21 : begin SDO=SD[7]; ACK2=I2C_SDAT; end6'd22 : SDO=SD[6];6'd23 : SDO=SD[5];6'd24 : SDO=SD[4];6'd25 : SDO=SD[3];6'd26 : SDO=SD[2];6'd27 : SDO=SD[1];6'd28 : SDO=SD[0];6'd29 : SDO=1'b1;//ACK
//stop 6'd30 : begin SDO=1'b0; SCLK=1'b0; ACK3=I2C_SDAT; end 6'd31 : SCLK=1'b1; 6'd32 : begin SDO=1'b1; END1=1; end
endcaseendendmodule
F-55
ECE 477 Final Report Spring 2009
////////////////////////////////////////////////////////////////////////////////// Author: lsilvest//// Create Date: 02/03/2008//// Module Name: sdram_controller//// Target Devices: Altera DE2//// Tool versions: Quartus II 7.2 Web Edition////// Description: This module is an SDRAM controller for 8-Mbyte SDRAM chip// PSC A2V64S40CTP-G7. Corresponding datasheet part number is// IS42S16400.//////////////////////////////////////////////////////////////////////////////////// Copyright (c) 2008 Authors//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.//////////////////////////////////////////////////////////////////////////////////This component is very slightly modified code from (insert link). This is what //handles the initialization of SDRAM, refreshing of the SDRAM, and the control //signals necessary for SDRAM. No further changes should be necessary.
module sdram_controller (input clk_i, input dram_clk_i, input rst_i, input dll_locked, // all ddr signals output [11:0] dram_addr, output [1:0] dram_bank, output dram_cas_n, output dram_cke, output dram_clk, output dram_cs_n, inout [15:0] dram_dq, output dram_ldqm, output dram_udqm, output dram_ras_n,
F-56
ECE 477 Final Report Spring 2009
output dram_we_n, // wishbone bus input [21:0] addr_i, input [31:0] dat_i, output [31:0] dat_o, input we_i, output ack_o, input stb_i, input cyc_i );
// row width 12 // column width 8 // bank width 2 // user address is specified as {bank,row,column} // CAS=3 BL=2 // ___ ___ parameter MODE_REGISTER = 12'b000000110001; parameter INIT_IDLE = 3'b000, INIT_WAIT_200us = 3'b001, INIT_INIT_PRE = 3'b010, INIT_WAIT_PRE = 3'b011, INIT_MODE_REG = 3'b100, INIT_WAIT_MODE_REG = 3'b101, INIT_DONE_ST = 3'b110;
parameter IDLE_ST = 4'b0000, REFRESH_ST = 4'b0001, REFRESH_WAIT_ST = 4'b0010, ACT_ST = 4'b0011, WAIT_ACT_ST = 4'b0100, WRITE0_ST = 4'b0101, WRITE1_ST = 4'b0110, WRITE_PRE_ST = 4'b0111, READ0_ST = 4'b1000, READ1_ST = 4'b1001, READ2_ST = 4'b1010, READ3_ST = 4'b1011, READ4_ST = 4'b1100, READ_PRE_ST = 4'b1101, PRE_ST = 4'b1110, WAIT_PRE_ST = 4'b1111;
// @ 133.333 MHz period is 7.5 nano cycle parameter TRC_CNTR_VALUE = 4'd9, // 9 cycles, == time to wait after refresh, 67.5ns // also time to wait between two ACT commands RFSH_INT_CNTR_VALUE = 24'd2000, // need 4096 refreshes for every 64_000_000 ns // so the # of cycles between refreshes is // 64000000 / 4096 / 7.5 = 2083 TRCD_CNTR_VALUE = 3'd3, // ras to cas delay 20ns
F-57
ECE 477 Final Report Spring 2009
// will also be used for tRP and tRSC WAIT_200us_CNTR_VALUE = 16'd27000; // 27000 200us
reg [21:0] address_r;
reg [11:0] dram_addr_r; reg [1:0] dram_bank_r; reg [15:0] dram_dq_r; reg dram_cas_n_r; reg dram_ras_n_r; reg dram_we_n_r;
reg [31:0] dat_o_r; reg ack_o_r; reg [31:0] dat_i_r; reg we_i_r; reg stb_i_r; reg oe_r;
reg [3:0] current_state; reg [3:0] next_state; reg [2:0] current_init_state; reg [2:0] next_init_state; reg init_done; reg [3:0] init_pre_cntr; reg [3:0] trc_cntr; reg [24:0] rfsh_int_cntr; reg [2:0] trcd_cntr; reg [15:0] wait_200us_cntr; reg do_refresh; assign dram_addr = dram_addr_r; assign dram_bank = dram_bank_r; assign dram_cas_n = dram_cas_n_r; assign dram_ras_n = dram_ras_n_r; assign dram_we_n = dram_we_n_r; assign dram_dq = oe_r ? dram_dq_r : 16'bz;
assign dat_o = dat_o_r; assign ack_o = ack_o_r; assign dram_cke = 1'b1;// dll_locked assign dram_cs_n = ~dll_locked; // chip select is always on in normal op assign dram_clk = dram_clk_i; assign dram_ldqm = 1'b0; // don't do byte masking assign dram_udqm = 1'b0; // don't do byte masking
initial begin rfsh_int_cntr = 0; wait_200us_cntr = 0; trc_cntr = 0;
F-58
ECE 477 Final Report Spring 2009
trcd_cntr = 0; init_done = 1'b0; init_pre_cntr = 1'b0; current_init_state = INIT_IDLE; next_init_state = INIT_IDLE; current_state = IDLE_ST; next_state = IDLE_ST; ack_o_r = 1'b0; dat_o_r = 32'b0; oe_r = 1'b0; end
// register the user command always@ (posedge clk_i) begin if (stb_i_r && current_state == ACT_ST) begin stb_i_r <= 1'b0; end else if (stb_i && cyc_i) begin address_r <= addr_i; dat_i_r <= dat_i; we_i_r <= we_i; stb_i_r <= stb_i; end end always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin wait_200us_cntr <= 0; end else if (current_init_state == INIT_IDLE) begin wait_200us_cntr <= WAIT_200us_CNTR_VALUE; end else begin wait_200us_cntr <= wait_200us_cntr - 16'b1; end end
// control the interval between refreshes: always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin rfsh_int_cntr <= 1'b0; // immediately initiate new refresh on reset end else if (current_state == REFRESH_WAIT_ST) begin do_refresh <= 1'b0; rfsh_int_cntr <= RFSH_INT_CNTR_VALUE; end else if (!rfsh_int_cntr) begin do_refresh <= 1'b1; end else begin rfsh_int_cntr <= rfsh_int_cntr - 24'b1; end end always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin trc_cntr <= 1'b0; end else if (current_state == PRE_ST || current_state == REFRESH_ST) begin trc_cntr <= TRC_CNTR_VALUE;
F-59
ECE 477 Final Report Spring 2009
end else begin trc_cntr <= trc_cntr - 4'b1; end end
// counter to control the activate always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin trcd_cntr <= 1'b0; end else if (current_state == ACT_ST || current_init_state == INIT_INIT_PRE || current_init_state == INIT_MODE_REG) begin trcd_cntr <= TRCD_CNTR_VALUE; end else begin trcd_cntr <= trcd_cntr - 3'b1; end end
always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin init_pre_cntr <= 1'b0; end else if (current_init_state == INIT_INIT_PRE) begin init_pre_cntr <= init_pre_cntr + 4'b1; end end
always@ (posedge clk_i) begin if (current_init_state == INIT_DONE_ST) init_done <= 1'b1; end
// state change always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin current_init_state <= INIT_IDLE; end else begin current_init_state <= next_init_state; end end
always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin current_state <= IDLE_ST; end else begin current_state <= next_state; end end
// initialization is fairly easy on this chip: wait 200us then issue // 8 precharges before setting the mode register always@ (*) begin case (current_init_state) INIT_IDLE: if (!init_done) next_init_state = INIT_WAIT_200us;
F-60
ECE 477 Final Report Spring 2009
else next_init_state = INIT_IDLE; INIT_WAIT_200us: if (!wait_200us_cntr) next_init_state = INIT_INIT_PRE; else next_init_state = INIT_WAIT_200us; INIT_INIT_PRE: next_init_state = INIT_WAIT_PRE;
INIT_WAIT_PRE: if (!trcd_cntr) // this is tRP if (init_pre_cntr == 4'd8) next_init_state = INIT_MODE_REG; else next_init_state = INIT_INIT_PRE; else next_init_state = INIT_WAIT_PRE;
INIT_MODE_REG: next_init_state = INIT_WAIT_MODE_REG; INIT_WAIT_MODE_REG: if (!trcd_cntr) /* tRSC */ next_init_state = INIT_DONE_ST; else next_init_state = INIT_WAIT_MODE_REG; INIT_DONE_ST: next_init_state = INIT_IDLE;
default: next_init_state = INIT_IDLE; endcase end
// this is the main controller logic: always@ (*) begin case (current_state) IDLE_ST: if (!init_done) next_state = IDLE_ST; else if (do_refresh) next_state = REFRESH_ST; else if (stb_i_r) next_state = ACT_ST; else next_state = IDLE_ST; REFRESH_ST: next_state = REFRESH_WAIT_ST;
REFRESH_WAIT_ST: if (!trc_cntr) next_state = IDLE_ST; else next_state = REFRESH_WAIT_ST;
ACT_ST: next_state = WAIT_ACT_ST; WAIT_ACT_ST: if (!trcd_cntr) if (we_i_r) next_state = WRITE0_ST; else next_state = READ0_ST; else next_state = WAIT_ACT_ST; WRITE0_ST: next_state = WRITE1_ST;
WRITE1_ST: next_state = WRITE_PRE_ST; WRITE_PRE_ST: next_state = PRE_ST; READ0_ST: next_state = READ1_ST;
F-61
ECE 477 Final Report Spring 2009
READ1_ST: next_state = READ2_ST; READ2_ST: next_state = READ3_ST;
READ3_ST: next_state = READ4_ST;
READ4_ST: next_state = READ_PRE_ST;
READ_PRE_ST: next_state = PRE_ST; PRE_ST: next_state = WAIT_PRE_ST; WAIT_PRE_ST: // if the next command was not another row activate in the same bank // we could wait tRCD only; for simplicity but at the detriment of // efficiency we always wait tRC if (!trc_cntr) next_state = IDLE_ST; else next_state = WAIT_PRE_ST;
default: next_state = IDLE_ST;
endcase end
// ack_o signal always@ (posedge clk_i) begin if (current_state == READ_PRE_ST || current_state == WRITE_PRE_ST) begin ack_o_r = 1'b1; end else if (current_state == WAIT_PRE_ST) begin ack_o_r = 1'b0; end end
// data always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin dat_o_r = 32'b0; dram_dq_r = 16'b0; oe_r = 1'b0; end else if (current_state == WRITE0_ST) begin dram_dq_r = dat_i_r[31:16]; oe_r = 1'b1; end else if (current_state == WRITE1_ST) begin dram_dq_r = dat_i_r[15:0]; oe_r = 1'b1; end else if (current_state == READ4_ST) begin // we should actually be reading this on READ3, but // because of delay the data comes a cycle later... dat_o_r[31:16] = dram_dq; dram_dq_r = 16'bZ; oe_r = 1'b0; end else if (current_state == READ_PRE_ST) begin dat_o_r[15:0] = dram_dq; dram_dq_r = 16'bZ;
F-62
ECE 477 Final Report Spring 2009
oe_r = 1'b0; end else begin dram_dq_r = 16'bZ; oe_r = 1'b0; end end
// address always@ (posedge clk_i) begin if (current_init_state == INIT_MODE_REG) begin dram_addr_r = MODE_REGISTER; end else if (current_init_state == INIT_INIT_PRE) begin dram_addr_r = 12'b10000000000; // precharge all end else if (current_state == ACT_ST) begin dram_addr_r = address_r[19:8]; dram_bank_r = address_r[21:20]; end else if (current_state == WRITE0_ST || current_state == READ0_ST) begin // enter column with bit a10 set to 1 indicating auto precharge: dram_addr_r = {4'b0100,address_r[7:0]}; dram_bank_r = address_r[21:20]; end else begin dram_addr_r = 12'b0; dram_bank_r = 2'b0; end end
// commands always@ (posedge clk_i) begin dram_ras_n_r <= (current_init_state == INIT_INIT_PRE || current_init_state == INIT_MODE_REG || current_state == REFRESH_ST || current_state == ACT_ST) ? 1'b0 : 1'b1; dram_cas_n_r <= (current_state == READ0_ST || current_state == WRITE0_ST || current_state == REFRESH_ST || current_init_state == INIT_MODE_REG) ? 1'b0 : 1'b1; dram_we_n_r <= (current_init_state == INIT_INIT_PRE || current_state == WRITE0_ST || current_init_state == INIT_MODE_REG ) ? 1'b0 : 1'b1; end
endmodule
F-63
ECE 477 Final Report Spring 2009
////////////////////////////////////////////////////////////////////////////////// Author: lsilvest//// Create Date: 02/03/2008//// Module Name: sdram//// Target Devices: Altera DE2//// Tool versions: Quartus II 7.2 Web Edition////// Description: This module is the top level module for the SDRAM controller.// It instantiates the PLL, testbench and controller.//////////////////////////////////////////////////////////////////////////////////// Copyright (c) 2008 Authors//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.//////////////////////////////////////////////////////////////////////////////////This component does the necessary port mapping for sdram_rw, sdram_pll. And //sdram_controller. The PLL takes a 50 MHz clock as input and outputs two 133 MHz //clocks and one 50 MHz clock. One of the two 133 MHz clock has a 3 ns delay for //communication with the SDRAM chip. This code is lightly modified code //(http://whoyouvotefor.info/altera_sdram.html)
module sdram ( input CLOCK_50, input nRST, input [15:0] DATA, input RecordAudio, input StartPlayback, input gotData, input readData,// output [1:0] LEDG,// output [0:0] LEDR, // SDRAM signals output [11:0] DRAM_ADDR, output DRAM_BA_0, output DRAM_BA_1, output DRAM_CAS_N,
F-64
ECE 477 Final Report Spring 2009
output DRAM_CKE, output DRAM_CLK, output DRAM_CS_N, inout [15:0] DRAM_DQ, output DRAM_LDQM, output DRAM_UDQM, output DRAM_RAS_N, output DRAM_WE_N,// output [7:0] LEDG, output [15:0] Audio_out, output done, output Datasread );
wire clk0; // 133.333 MHZ wire clk1; // 50 MHZ user side wire clk2; // 133.333 MHZ -3ns wire [1:0] dram_bank; wire dll_locked;
wire [21:0] addr_i; wire [31:0] dat_i; wire [31:0] dat_o; wire we_i; wire ack_o; wire stb_i; wire cyc_i; wire rst_i;
reg [15:0] counter;
//assign LEDG[0] = dll_locked; assign {DRAM_BA_1, DRAM_BA_0} = dram_bank; assign rst_i = nRST;
sdram_pll pll_inst ( .areset(!nRST), .inclk0(CLOCK_50), .c0(clk0), .c1(clk1), .c2(clk2), .locked (dll_locked) );
sdram_controller sdram_controller_inst ( .clk_i(clk0), .dram_clk_i(clk2), .rst_i(rst_i), .dll_locked(dll_locked), // all sdram signals .dram_addr(DRAM_ADDR), .dram_bank(dram_bank), .dram_cas_n(DRAM_CAS_N), .dram_cke(DRAM_CKE),
F-65
ECE 477 Final Report Spring 2009
.dram_clk(DRAM_CLK), .dram_cs_n(DRAM_CS_N), .dram_dq(DRAM_DQ), .dram_ldqm(DRAM_LDQM), .dram_udqm(DRAM_UDQM), .dram_ras_n(DRAM_RAS_N), .dram_we_n(DRAM_WE_N), // wishbone bus .addr_i(addr_i), .dat_i(dat_i), .dat_o(dat_o), .we_i(we_i), .ack_o(ack_o), .stb_i(stb_i), .cyc_i(cyc_i) );
sdram_rw rw_inst ( .clk_i(clk1), .rst_i(rst_i), .addr_i(addr_i), .dat_i(dat_i), .dat_o(dat_o), .we_i(we_i), .ack_o(ack_o), .stb_i(stb_i), .cyc_i(cyc_i), .Record(RecordAudio), .Playback(StartPlayback), .Audio_out(Audio_out),// .LEDflag(LEDG[7:0]), .DATA(DATA), .gotData(gotData), .readData(readData), .done(done), .read(Datasread)// .red_led(LEDR[0]),// .green_led(LEDG[1]) );
Endmodule
F-66
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--This component takes the data captured from the SPI and sets a command that is used --to determine whether sendData or sendRecordedAudio is used as well as whether to --simply stream audio, record audio, play recorded audio, or stream audio with a --flange effect. While currently fully implemented, this component would need to be --updated if more capabilities were added.
ENTITY itrptSPI ISPORT(
CLK : in std_logic;nRST : in std_logic;DATA_in : in std_logic_vector(7 downto 0);DATA_out : out std_logic_vector(7 downto 0);command : out std_logic_vector(7 downto 0);volume : out std_logic_vector(1 downto 0);SoundReset : out std_logic
);end itrptSPI;
architecture behavioral of itrptSPI is signal iDATA_out : std_logic_vector(7 downto 0);signal nextcommand, icommand : std_logic_vector(7 downto 0);signal nextvolume, ivolume : std_logic_vector(1 downto 0);signal iSoundReset, nextSoundReset : std_logic;begin
Reg : process(clk, nRST)begin
if (nRST = '0') thenicommand <= x"00";ivolume <= "00";iSoundReset <= '1';
elsif rising_edge(clk) thenicommand <= nextcommand;ivolume <= nextvolume;iSoundReset <= nextSoundReset;
end if;end process;
StateMachine : process(clk, ivolume, iSoundReset, icommand, DATA_in)begin
nextcommand <= icommand;nextvolume <= ivolume;nextSoundReset <= '1';case DATA_in is
when x"00" =>iDATA_out <= x"00";nextSoundReset <= '1';
when x"19" => --Stream commandiDATA_out <= x"19";nextcommand <= x"19";
when x"05" => --Record CommandiDATA_out <= x"05";nextcommand <= x"05";
when x"0A" => --Stop Record Command iDATA_out <= x"0A";
F-67
ECE 477 Final Report Spring 2009
nextcommand <= x"0A";when x"0F" => --Playback command
iDATA_out <= x"0F";nextcommand <= x"0F";
when x"14" => --Stop Playback commandiDATA_out <= x"14";nextcommand <= x"14";
when x"22" => --Flange CommandiDATA_out <= x"22";nextcommand <= x"22";
when x"28" =>iDATA_out <= x"28";nextcommand <= x"28";
when x"35" => --Volume upiDATA_out <= x"35";nextvolume <= "01";nextSoundReset <= '0';
when x"45" => --Volume downiDATA_out <= x"45";nextvolume <= "10";nextSoundReset <= '0';
when others => iDATA_out <= x"00";nextcommand <= x"01";
end case;end process;DATA_out <= iDATA_out;command <= icommand;volume <= ivolume;SoundReset <= iSoundReset;
end behavioral;
F-68
ECE 477 Final Report Spring 2009
//This is the receiver for SPI. The bus (SCK, SSEL, and MOSI) are sampled at//the FPGA's system clock. This allows the microcontroller and FPGA to communicate//even though they operate at different clock speeds. This is only possible because//the FPGA's clock is much faster than the microcontroller's. The most significant//bit is sent/received first.//Slightly modified from code at http://www.fpga4fun.com/SPI2.html
module SPI_slave(CLK, nRST, SCK, MOSI, MISO, SSEL, DATA_RECEIVED, DATA_TO_SEND);input CLK;input nRST;input SCK, SSEL, MOSI;input [7:0] DATA_TO_SEND;output MISO;
output [7:0] DATA_RECEIVED;//output [7:0] DATA_SENT;
//sample SCKreg [2:0] SCKr; always @(posedge CLK) SCKr <= {SCKr[1:0], SCK};wire SCK_risingedge = (SCKr[2:1]==2'b01);wire SCK_fallingedge = (SCKr[2:1]==2'b10);
//sample SSELreg [2:0] SSELr; always @(posedge CLK) SSELr <= {SSELr[1:0], SSEL};wire SSEL_active = ~SSELr[1]; //SSEL is active lowwire SSEL_startmessage = (SSELr[2:1]==2'b10);wire SSEL_endmessage = (SSELr[2:1]==2'b01);
//sample MOSIreg [1:0] MOSIr; always @(posedge CLK) MOSIr <= {MOSIr[0], MOSI};wire MOSI_data = MOSIr[1];
reg [2:0] bitcnt; //counter for bits received (counts to 8)
reg byte_received;reg [7:0] byte_data_received;
initial beginbitcnt <= 3'b000;
end
//If SSEL is low and SCK goes high, increment the bit counter//and shift a bit into the receive register. If SSEL is high,//reset the bit counter.always @(negedge nRST or posedge CLK)begin
if(!nRST)begin
bitcnt <= 3'b000;byte_data_received <= 8'h00;
endelsebegin
if(~SSEL_active)bitcnt <= 3'b000;
elseif(SCK_risingedge)begin
F-69
ECE 477 Final Report Spring 2009
bitcnt <= bitcnt + 3'b001;byte_data_received <= {byte_data_received[6:0], MOSI_data};
endend
end
//When 8 bits are received, set the byte received flag.always @(posedge CLK) begin
byte_received <= SSEL_active && SCK_risingedge && (bitcnt==3'b111);end
//When the byte received flag is set, output the receive register to the//rest of the FPGA.reg [7:0] DATA_RECEIVED;always @(posedge CLK) if(byte_received) DATA_RECEIVED <= byte_data_received;//reg [7:0] DATA_SENT;//always @(posedge CLK) if(byte_received) DATA_SENT <= byte_data_sent;
reg [7:0] byte_data_sent;
//reg [7:0] cnt;//always @(posedge CLK) if(SSEL_startmessage) cnt<=cnt+8'h1;
//If SSEL goes low, copy the data to be sent from the rest of the FPGA//to the send data register. If SSEL is low and SCK goes low, shift a bit//out.always @(negedge nRST or posedge CLK)begin
if(!nRST)begin
byte_data_sent <= 8'h00;endelseif(SSEL_active)begin
if(SSEL_startmessage)byte_data_sent <= DATA_TO_SEND;
elseif(SCK_fallingedge)begin
if(bitcnt==3'b000)byte_data_sent <= 8'h00;
elsebyte_data_sent <= {byte_data_sent[6:0], 1'b0};
endend
end
assign MISO = byte_data_sent[7];//assign DATA_RECEIVED = byte_data_received;
Endmodule
F-70
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--This is a component that connects the top level component to two smaller components, --CLOCK_500 and I2C, that are used to configure the Audio CODEC. This component is --fully implemented.
ENTITY sound ISPORT(
CLK : in std_logic;nRST : in std_logic;VolumeReset : in std_logic;AUD_ADCLRC :in std_logic;volume : in std_logic_vector(1 downto 0);AUD_XCK : out std_logic;I2C_SCLK_2 : out std_logic;I2C_SDAT : inout std_logic
);end sound;
architecture structural of sound issignal iCLOCK, iEND1, iGO, SDO_scrap, ACKscrap : std_logic;signal iDATA : std_logic_vector(23 downto 0);signal ON1scrap, KEYON : std_logic;signal iCLOCK2 : std_logic;signal i2c_sclk : std_logic;
component CLOCK_500 isport (
CLOCK : in std_logic;END1 : in std_logic;RESET : in std_logic;volume : in std_logic_vector(1 downto 0);DATA : out std_logic_vector(23 downto 0);GO : out std_logic;CLOCK_2 : out std_logic;CLOCK_500 : out std_logic);
end component;component I2C is
port (CLOCK : in std_logic;I2C_SCLK : out std_logic ; --I2C CLOCKI2C_SDAT : inout std_logic; --I2C DATAI2C_DATA : in std_logic_vector(23 downto 0);--DATA:
[SLAVE_ADDR,SUB_ADDR,DATA]GO : in std_logic; --GO transforEND1 : out std_logic; --END transfor W_R : in std_logic; --/W_RACK : out std_logic; --ACKRESET : in std_logic --TEST);
end component;begin
CLOCK_500_Block : CLOCK_500port map (
F-71
ECE 477 Final Report Spring 2009
CLOCK => CLK,CLOCK_500 => iCLOCK,DATA => iData,END1 => iEND1,RESET => volumeReset, volume => volume,GO => iGO,CLOCK_2 => iCLOCK2);
I2C_Block : I2Cport map (
CLOCK => iCLOCK, I2C_SCLK => I2C_SCLK,I2C_SDAT => I2C_SDAT,I2C_DATA => iData, GO => iGO, END1 => iEND1,W_R => AUD_ADCLRC, ACK => ACKscrap, RESET => '1' );
i2c_sclk_2 <= i2c_sclk;AUD_XCK <= iCLOCK2;
end structural;
F-72
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--SendRecordedAudio is very similar to SendData but where sendData is used to --interface to getData, sendRecordedAudio is used in conjuction with either memory or --with the delay component. When in an idle state and in a mode where audio should be --either read for memory or manipulated, this component waits to be informed that new --data is ready to be sent to the CODEC. When there is new data ready to be sent to --the CODEC, sendRecordedAudio stores this data has in a register. After this, --sendRecordedAudio waits for a transition on the DAC clock and then shifts out the 16 --bits based on a clock generated by the CODEC. Once this is done, a flag is set to --inform the appropriate component that new data is being requested. This component is --fully implemented.
ENTITY SendRecordedAudio ISPORT(
BCLK : in std_logic;DACLRC : in std_logic;iDATA : in std_logic_vector(15 downto 0);nRST : in std_logic;newData : in std_logic;playRecorded : in std_logic;DACDAT : out std_logic;GetNewData : out std_logic
);end sendRecordedAudio;
architecture behavioral of sendRecordedAudio is
signal counter, nextcounter : std_logic_vector(3 downto 0);type statetype is (idle, sendData);signal state, nextstate : statetype;signal Data, nextData : std_logic_vector(15 downto 0);signal iDACDAT : std_logic;signal Q2, Q1, Dataregistered, nextDataregistered : std_logic;signal iGetNewData, nextGetNewData : std_logic;begin
StateReg : process (bclk, nrst)begin
if (nrst = '0') thencounter <= (others => '0');state <= IDLE;Data <= (others => '0');Q1 <= '0';Q2 <= '0';Dataregistered <= '0';iGetNewData <= '0';
elsif falling_edge(BCLK) thenstate <= nextstate;counter <= nextcounter;Data <= nextData;Q1 <= DACLRC;Q2 <= Q1;Dataregistered <= nextDataregistered;iGetNewData <= nextGetNewData;
end if;end process;
F-73
ECE 477 Final Report Spring 2009
StateMachine: process(iGetNewData, newData, playRecorded, Q1, Q2, state, counter, iDATA, Dataregistered, DATA)
beginnextstate <= state;iDACDAT <= '0';nextcounter <= counter;nextDataregistered <= Dataregistered;nextData <= Data;nextGetNewData <= iGetNewData;case state is
when IDLE =>if (Playrecorded = '1' and Dataregistered = '0' and newData =
'0') thennextGetNewData <= '1';
elsif (PlayRecorded = '1' and Dataregistered = '1' and ((Q1='0' and Q2 ='1') or (Q1='1' and Q2 = '0'))) then
iDACDAT <= DATA(15);nextData <= DATA(14 downto 0) & '0';nextstate <= sendData;nextDataregistered <= '0';
elsif (PlayRecorded = '1' and newData = '1') thennextData <= iDATA;nextDataregistered <= '1';nextGetNewData <= '0';
end if;when sendData =>
iDACDAT <= DATA(15);nextData <= Data(14 downto 0) & '0';if (counter = x"E") then
nextGetNewData <= '1'; nextcounter <= x"0";nextstate <= idle;
elsenextcounter <= counter + 1;nextstate <= state;
end if;when others => nextstate <= IDLE;
end case;end process;GetNewData <= iGetNewData;DACDAT <= iDACDAT;
end behavioral;
F-74
ECE 477 Final Report Spring 2009
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.ALL;
--When audio data is being streamed, the audio data from getData is passed here. A --shift register is used send an audio data bit on the Clock being generated by the --CODEC. sendData sits in an IDLE state until a transition on the DAC Clock. This --component is fully implemented, but could likely be absorbed by the --sendRecordedAudio component.
ENTITY sendData ISPORT(
BCLK : in std_logic;DACLRC : in std_logic;iDATA : in std_logic_vector(15 downto 0);nRST : in std_logic;Stream : in std_logic;DACDAT : out std_logic;readData : out std_logic
);end sendData;
architecture behavioral of sendData is
signal counter, nextcounter : std_logic_vector(3 downto 0);type statetype is (IDLE, sendData);signal state, nextstate : statetype;signal Data, nextData : std_logic_vector(15 downto 0);signal iDACDAT : std_logic;signal Q2, Q1 : std_logic;begin
StateReg : process (bclk, nrst)begin
if (nrst = '0') thencounter <= (others => '0');state <= IDLE;Data <= (others => '0');Q1 <= '0';Q2 <= '0';
elsif falling_edge(BCLK) thenstate <= nextstate;counter <= nextcounter;Data <= nextData;Q1 <= DACLRC;Q2 <= Q1;
end if;end process;
StateMachine: process(Q1, Q2, state, counter, iDATA, DACLRC, nRST, DATA, Stream)begin
nextstate <= state;iDACDAT <= '0';nextcounter <= counter;nextData <= Data;readData <= '0';case state is
when IDLE =>
F-75
ECE 477 Final Report Spring 2009
if (((Q1='0' and Q2 ='1') or (Q1='1' and Q2 = '0'))) theniDACDAT <= iDATA(15);nextData <= iDATA(14 downto 0) & '0';nextstate <= sendData;readData <= '1';
end if;when sendData =>
iDACDAT <= DATA(15);nextData <= Data(14 downto 0) & '0';if (counter = x"E") then
nextcounter <= x"0";nextstate <= idle;
elsenextcounter <= counter + 1;nextstate <= state;
end if;end case;
end process;DACDAT <= iDACDAT;
-- LEDR <= LEDs;end behavioral;
F-76
ECE 477 Final Report Spring 2009
////////////////////////////////////////////////////////////////////////////////// Author: lsilvest//// Create Date: 02/03/2008//// Module Name: sdram_rw//// Target Devices: Altera DE2//// Tool versions: Quartus II 7.2 Web Edition////// Description: This module provides a simple test bench for the SDRAM// controller. It sequentially writes all positions in// memory, pauses for a while and then reads back all// positions comparing them to the written value. The// green LEDG1 indicates the test passed. The red LEDR0// indicates at least one of the readbacks failed//////////////////////////////////////////////////////////////////////////////////// Copyright (c) 2008 Authors//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.////////////////////////////////////////////////////////////////////////////////
//This component is what is used to read and write to the sdram controller. It is //heavily modified code from (insert link here). While fully functional and //implemented, variable names could be renamed more appropriately, and the code could //be cleaned up in general. There are currently two inferred latches, however these do //not affect the performance of the code and are created because the registers are //only assigned in conditional logic (however, it is set up in a manner that does not //create problems).
module sdram_rw ( input clk_i, input rst_i, input Record, input Playback, input [31:0] dat_o, input [15:0] DATA, input gotData,
F-77
ECE 477 Final Report Spring 2009
input readData, input ack_o, output we_i, output [21:0] addr_i, output [31:0] dat_i, output stb_i, output cyc_i, output [15:0] Audio_out, output done, output read );
parameter FLAGIDLE = 4'b0000, check0high = 4'b0001,
check1high = 4'b0010;
parameter START_WRITE_ST = 4'b0000, WRITE_ST = 4'b0001, WAIT_WRITE_ACK_ST = 4'b0010, READ_ST = 4'b0011, WAIT_READ_ACK_ST = 4'b0100, WRITE_WAIT_ST = 4'b0101, START_READ_ST = 4'b0110, READ_WAIT_ST = 4'b0111, IDLE = 4'b1000; // //parameter MAX_RW = 24'd100000; // 200000 is the full 8 Mbytes of memory parameter R_TO_W_WAIT_TIME = 24'd12500000;// parameter INITIAL_MEM_VALUE = 32'd12345678; reg [21:0] addr_i_r; reg [31:0] dat_i_r; reg [15:0] LEDs_r; reg [7:0] LEDGs_r; reg we_i_r; reg stb_i_r; reg cyc_i_r; reg [21:0] raddr_i_r; reg [21:0] waddr_i_r; reg full; reg validData;
reg [23:0] rw_cntr; reg [23:0] cntr; reg [31:0] number; reg [31:0] mem_value; reg [3:0] state; // reg [3:0] flagstate;// reg startrecflag;// reg stoprecflag;// reg playrecflag; reg done_flag; // reg [0:0] red_led_r;// reg [0:0] green_led_r; reg [2:0] gotDatar; always @(posedge clk_i) gotDatar <= {gotDatar[1:0], gotData}; wire gotData_risingedge = (gotDatar[2:1]==2'b01);
F-78
ECE 477 Final Report Spring 2009
reg [2:0] readDatar; always @(posedge clk_i) readDatar <= {readDatar[1:0], readData}; wire readData_risingedge = (readDatar[2:1]==2'b01); reg read_r = 1'b0; assign Audio_out = LEDs_r; assign dat_i = dat_i_r; assign read = read_r; assign addr_i = addr_i_r; assign we_i = we_i_r; assign stb_i = stb_i_r; assign cyc_i = cyc_i_r; assign done = done_flag;
initial begin cntr <= 24'b0; rw_cntr <= 24'b0; state <= IDLE; we_i_r <= 1'b0; addr_i_r <= 22'b0; waddr_i_r <= 22'b0; raddr_i_r <= 22'b0; stb_i_r <= 1'b0; cyc_i_r <= 1'b0; LEDs_r <= 16'b0; full <= 1'b0; end always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin state <= IDLE; rw_cntr <= 24'b0; addr_i_r <= 22'b0; waddr_i_r <= 22'b0;
raddr_i_r <= 22'b0; full <= 1'b0;
// red_led_r <= 1'b0; end else begin case (state)
IDLE:begin
if (Record) beginstate <= START_WRITE_ST;
end else if (Playback) beginstate <= START_READ_ST;
endend
START_WRITE_ST: begin
addr_i_r <= waddr_i_r;state <= WRITE_ST;
end WRITE_ST:
F-79
ECE 477 Final Report Spring 2009
beginif (!Record) begin
state <= IDLE;end else if (full) begin
state <= IDLE;end else if (gotData_risingedge) begin
stb_i_r <= 1'b1;cyc_i_r <= 1'b1;dat_i_r <= DATA;LEDs_r <= DATA;we_i_r <= 1'b1;state <= WAIT_WRITE_ACK_ST;
end end WAIT_WRITE_ACK_ST: if (ack_o) begin state <= WRITE_WAIT_ST; stb_i_r <= 1'b0; cyc_i_r <= 1'b0; end WRITE_WAIT_ST: begin if (waddr_i_r < 22'b1111111111111111111000) begin waddr_i_r <= waddr_i_r + 22'd2; addr_i_r <= addr_i_r + 22'd2; state <= WRITE_ST; end else begin state <= IDLE; full <= 1'b1; end end START_READ_ST:
begin // if (!cntr) begin // wait for R_TO_W_WAIT_TIME
state <= READ_ST;//raddr_i_r <= 22'b0;addr_i_r <= raddr_i_r;rw_cntr <= 24'b0;end
READ_ST: begin if (!Playback) begin
state <= IDLE;end
elseif (readData_risingedge) begin
stb_i_r <= 1'b1;cyc_i_r <= 1'b1;we_i_r <= 1'b0;state <= WAIT_READ_ACK_ST;
end else begin // if (rw_cntr < MAX_RW - 1) state <= READ_ST;
end end WAIT_READ_ACK_ST: if (ack_o) begin
F-80
ECE 477 Final Report Spring 2009
state <= READ_WAIT_ST; LEDs_r <= dat_o; stb_i_r <= 1'b0; cyc_i_r <= 1'b0; read_r <= 1'b1; end
READ_WAIT_ST: begin
read_r <= 1'b0;if(addr_i_r < waddr_i_r) begin
state <= READ_ST; // increment address: raddr_i_r <= raddr_i_r + 22'd2; addr_i_r <= addr_i_r + 22'd2; //LEDs_r <= raddr_i_r[21:6]; //LEDGs_r[7:2] <= raddr_i_r[5:0];
end else begindone_flag <= 1'b1;read_r <= 1'b0;state <= IDLE;
end end // case: READ_WAIT_ST endcase // case (state) end // else: !if(rst_i) end // always@ (posedge clk_i)
always@ (negedge rst_i or posedge clk_i) begin if (!rst_i) begin cntr <= 24'b0; end else if (state == WRITE_WAIT_ST) begin cntr <= R_TO_W_WAIT_TIME; end else cntr <= cntr - 24'b1; endendmodule
F-81
ECE 477 Final Report Fall 2008
Appendix G: FMECA Worksheet
Table G-1: Power Supply Functional BlockFailure No. Failure Mode
Possible Causes Failure Effects
Method of Detection Criticality
A1 5V Output = 0V
Failure of U8, SW1, J1, C36, C37, C45 or external short
Device does not function Observation Low
A2 5V Output > 5V Failure of U8
Possible damage to rest of circuitry, possible fire Observation High
A35V Output out of tolerance
U8, C36, C37, C45 Unpredictable operation Observation High
A4 3.3V Output = 0V
Failure No. A1; Failure of U10, C42, C44
Device does not function
LCD turns on but no user interface Low
A53.3V Output > 3.3V
Failure No. A2, A3; Failure of U10
Possible damage to rest of circuitry, possible fire
LCD turns on but no user interface High
A63.3V Output out of tolerance
Failure No. A2, A3; U10, C42, C44 Unpredictable operation Observation High
A7 2.5V Output = 0V
Failure No. A1; Failure of U10, C42, C43
Device does not function
LCD turns on but no user interface Low
A82.5V Output > 2.5V
Failure No. A2, A3; Failure of U10
Possible damage to rest of circuitry, possible fire
LCD turns on but no user interface High
A92.5V Output out of tolerance
Failure No. A2, A3; U10, C42, C43 Unpredictable operation Observation High
A10 1.2V Output = 0V
Failure No. A1; Failure of U11, C40, C41, R12
Device does not function
User interface, but no device functionality Low
A111.2V Output > 1.2V
Failure No. A2, A3; Failure of U11
Possible damage to rest of circuitry, possible fire
User interface, but no device functionality High
A121.2V Output out of tolerance
Failure No. A2, A3; U11, C40, C41, R12 Unpredictable operation Observation High
Table G-2: Audio Circuitry Functional BlockFailure No. Failure Mode
Possible Causes Failure Effects
Method of Detection Criticality
B1
Unexpected audio on two input channels
Failure of U4, J9, C24 and C39, R6 and R14
Unexpected audio on both output channels Observation Low
G-1
ECE 477 Final Report Fall 2008
B2
Unexpected audio on one input channel
Failure of U4, C24 or C39, R6 or R14
Unexpected audio on one output channel Observation Low
B3
Unexpected audio on two output channels
Failure No. B1; Failure of U4, J3, C25 and C95, R9 and R21
Unexpected audio on both output channels Observation Low
B4
Unexpected audio on one output channel
Failure No. B2; Failure of U4, C25 or C95, R9 or R21
Unexpected audio on one output channel Observation Low
Table G-3: FPGA Circuitry Functional BlockFailure No. Failure Mode
Possible Causes Failure Effects
Method of Detection Criticality
C1 No clock signalFailure of U7, U10, or C100
Device does not function Observation Low
C2No clean clock signal
Failure of U7, U10, or C100 Unpredictable operation Observation Low
C3Currupted data stored Software or U3
Unexpected audio on output channels Observation Medium
C4U1 I/O stuck high or low
Software, short/open-circuit in U1 Unpredictable operation Observation Medium
Table G-4: Microcontroller Circuitry Functional BlockFailure No. Failure Mode
Possible Causes Failure Effects
Method of Detection Criticality
D1U2 I/O stuck high or low
Software, short/open-circuit in U2 Unpredictable operation Observation Medium
D2Pushbuttons do not work
Software, unconnected wires, failure of U10 Device is unresponsive Observation Low
D3LCD does not work
Failure of U8, unconnected wires LCD does not turn on Observation Low
D4LCD displays unexpected data Software
LCD displays unexpected data Observation Low
G-2