EE 477 Final Report - College of Engineering - Purdue … · Web viewParameter Value Assumptions C1...

176
ECE 477 Final Report Spring 2009 Team 6 ALF Team Members: #1: Andrew Hartnett Signature: ____________________ Date: _________ #2: David Eslinger Signature: ____________________ Date: _________ #3: Curt Schieler Signature: ____________________ Date: _________ #4: Ken Pesyna Signature: ____________________ Date: _________

Transcript of EE 477 Final Report - College of Engineering - Purdue … · Web viewParameter Value Assumptions C1...

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

Figure 1.1: Block Diagram

Figure 1.2: Completed Project

-2-

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

Figure C-2: FPGA, Bypass capacitors, Power, Debugging headers

C-2

ECE 477 Final Report Spring 2009

Figure C-3: SDRAM, Audio CODEC, FPGA

C-3

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

Figure D-2: PCB Bottom

D-2

ECE 477 Final Report Spring 2009

Figure D-3: PCB Power layer

D-3

ECE 477 Final Report Spring 2009

Figure D-4: PCB ground layer

D-4

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

return(0);}

F-21

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