This document describes a final project to create a serial to Morse code converter. The project was completed by two students for a digital electronics course. Their system takes serial input from an AD2 board at 9,600 bits/sec, stores up to 100 characters in a buffer, and outputs the corresponding Morse code signals for each character using light and sound. The system is made up of several blocks including SCI receivers and transmitters, a character checker, buffer, Morse code translator, interpreter, and oscillator. Each block was designed and tested individually before integrating the full system. However, during testing the integrated system did not function correctly, possibly due to wiring issues.
This presentation has given a brief introduction and working of CMOS Logic Structures which includes MOS logic, CMOS logic, CMOS logic structure, CMOS complementary logic, pass transistor logic, bi CMOS logic, pseudo –nMOS logic, CMOS domino logic, Cascode Voltage Switch Logic(CVSL), clocked CMOS logic(c²mos), dynamic CMOS logic
This presentation has given a brief introduction and working of CMOS Logic Structures which includes MOS logic, CMOS logic, CMOS logic structure, CMOS complementary logic, pass transistor logic, bi CMOS logic, pseudo –nMOS logic, CMOS domino logic, Cascode Voltage Switch Logic(CVSL), clocked CMOS logic(c²mos), dynamic CMOS logic
Interconnects occupy upto 90% of the area in Reconfigurable Architectures and affect the speed and noise of the chip. This presentations gives briefs about interconnects, particularly in context of Reconfigurable Architecture (eg FPGAs)
I have prepared it to create an understanding of delay modeling in VLSI.
Regards,
Vishal Sharma
Doctoral Research Scholar,
IIT Indore
vishalfzd@gmail.com
A fundamental introduction to Intellectual Property in VLSI domain. Starts from basics and includes types of IPs and their examples, life cycle of an IP and other few topics in brief in an interactive Q-A manner.
The material is also available at : https://wordpress.com/stats/day/vlsifundamentals.wordpress.com
Here are the all short channel effects that you require.It consist of:-
Drain Induced Barrier Lowering
Hot electron Effect
Impact Ionization
Surface Scattering
Velocity saturation
Verilog HDL (Hardware Description Language) Training Course for self-taught instructional. User should be familiar with basic digital and logic design. Helpful to have a Verilog simulator while going through examples.
Analysis and Implementation of Hard-Decision Viterbi Decoding In Wireless Com...IJERA Editor
Convolutional codes are also known as Turbo codes because of their error correction capability. These codes are
also awarded as Super product codes, because these codes have replaced the backward error correction codes.
Turbo codes are much more efficient than previous backward error correction codes because these are Forward
error correction (FEC) codes and there is no need for a feedback link to request the transmitter for
retransmission of data, when bits are corrupted in the information channel. A Viterbi decoder decodes stream of
digital data bits that has been encoded by Convolutional encoder. In this paper we introduce a RSC (Recursive
Systematic Convolutional) encoder with constraint length of 2 code rate of 1/3. The RSC encoder and Viterbi
decoder both are implemented on paper, as well as in MATLAB. Simulation results are also presented by using
MATLAB.
Interconnects occupy upto 90% of the area in Reconfigurable Architectures and affect the speed and noise of the chip. This presentations gives briefs about interconnects, particularly in context of Reconfigurable Architecture (eg FPGAs)
I have prepared it to create an understanding of delay modeling in VLSI.
Regards,
Vishal Sharma
Doctoral Research Scholar,
IIT Indore
vishalfzd@gmail.com
A fundamental introduction to Intellectual Property in VLSI domain. Starts from basics and includes types of IPs and their examples, life cycle of an IP and other few topics in brief in an interactive Q-A manner.
The material is also available at : https://wordpress.com/stats/day/vlsifundamentals.wordpress.com
Here are the all short channel effects that you require.It consist of:-
Drain Induced Barrier Lowering
Hot electron Effect
Impact Ionization
Surface Scattering
Velocity saturation
Verilog HDL (Hardware Description Language) Training Course for self-taught instructional. User should be familiar with basic digital and logic design. Helpful to have a Verilog simulator while going through examples.
Analysis and Implementation of Hard-Decision Viterbi Decoding In Wireless Com...IJERA Editor
Convolutional codes are also known as Turbo codes because of their error correction capability. These codes are
also awarded as Super product codes, because these codes have replaced the backward error correction codes.
Turbo codes are much more efficient than previous backward error correction codes because these are Forward
error correction (FEC) codes and there is no need for a feedback link to request the transmitter for
retransmission of data, when bits are corrupted in the information channel. A Viterbi decoder decodes stream of
digital data bits that has been encoded by Convolutional encoder. In this paper we introduce a RSC (Recursive
Systematic Convolutional) encoder with constraint length of 2 code rate of 1/3. The RSC encoder and Viterbi
decoder both are implemented on paper, as well as in MATLAB. Simulation results are also presented by using
MATLAB.
VoCoRoBo: Remote Speech Recognition and Tilt Sensing Multi-Robotic SystemSagun Man Singh Shrestha
This work is based on the implementation of real-time speech recognition using DSP algorithms such as Chebyshev IIR filters, accelerometer for tilt-sensing and establishment of short-range wireless secure link with ARC4 cipher, all using low-cost 8-bit ATmega microcontrollers. The robot implements a simple but effective algorithm for comparing the spoken word with a dictionary of fingerprints using a modified Euclidean distance calculation. It also includes the ability to securely control the navigation of multiple robots located at remote locations wirelessly from the Control Module and also gather the various environmental data collected by the Robot Modules and display them in the back to Control. Considering the time-critical algorithms actually requiring large computations as well as a variety of sensors interfaced in the system, this project can demonstrate how one can build an expansible multi-robotic system from cheap and ubiquitous electronics.
International Journal of Engineering Research and Applications (IJERA) is an open access online peer reviewed international journal that publishes research and review articles in the fields of Computer Science, Neural Networks, Electrical Engineering, Software Engineering, Information Technology, Mechanical Engineering, Chemical Engineering, Plastic Engineering, Food Technology, Textile Engineering, Nano Technology & science, Power Electronics, Electronics & Communication Engineering, Computational mathematics, Image processing, Civil Engineering, Structural Engineering, Environmental Engineering, VLSI Testing & Low Power VLSI Design etc.
International Journal of Engineering Research and Applications (IJERA) is an open access online peer reviewed international journal that publishes research and review articles in the fields of Computer Science, Neural Networks, Electrical Engineering, Software Engineering, Information Technology, Mechanical Engineering, Chemical Engineering, Plastic Engineering, Food Technology, Textile Engineering, Nano Technology & science, Power Electronics, Electronics & Communication Engineering, Computational mathematics, Image processing, Civil Engineering, Structural Engineering, Environmental Engineering, VLSI Testing & Low Power VLSI Design etc.
For the Students of Diploma in IT as well as CM
Scheme: G
Semester:4th
Subject:Microprocessor & Programming.
Subject.Code: 17431
Chapter.No: 1
Title: Basics of Micro-Processor
Question.No.1: Draw & Explain the Pin-Diagram of 8085 Micro-Processor.
Welcome to International Journal of Engineering Research and Development (IJERD)IJERD Editor
call for paper 2012, hard copy of journal, research paper publishing, where to publish research paper,
journal publishing, how to publish research paper, Call For research paper, international journal, publishing a paper, IJERD, journal of science and technology, how to get a research paper published, publishing a paper, publishing of journal, publishing of research paper, reserach and review articles, IJERD Journal, How to publish your research paper, publish research paper, open access engineering journal, Engineering journal, Mathemetics journal, Physics journal, Chemistry journal, Computer Engineering, Computer Science journal, how to submit your paper, peer reviw journal, indexed journal, reserach and review articles, engineering journal, www.ijerd.com, research journals
Serial Communication Interface with Error Detectioniosrjce
UART is used for serial data communication. UART is a piece of computer hardware that translates
between parallel bits of data and serial bits. UART is usually an integrated circuit used for serial
communications over a computer or peripheral device serial port. Bits have to be moved from one place to
another using wires or some other medium. Over many miles, the expense of the wires becomes large. To reduce
the expense of long communication links carrying several bits in parallel, data bits are sent sequentially. Errors
may occur either internally or externally while we transmit information from source to destination. The errors
generated during the transmission would affect the performance of the overall system. In order to reduce the
errors we should incorporate any error detecting schemes like hamming decoder, check parity systems etc.
Different serial communication devices are available.
IJCER (www.ijceronline.com) International Journal of computational Engineeri...ijceronline
Call for paper 2012, hard copy of Certificate, research paper publishing, where to publish research paper,
journal publishing, how to publish research paper, Call For research paper, international journal, publishing a paper, IJCER, journal of science and technology, how to get a research paper published, publishing a paper, publishing of journal, publishing of research paper, research and review articles, IJCER Journal, How to publish your research paper, publish research paper, open access engineering journal, Engineering journal, Mathematics journal, Physics journal, Chemistry journal, Computer Engineering, Computer Science journal, how to submit your paper, peer review journal, indexed journal, research and review articles, engineering journal, www.ijceronline.com, research journals,
yahoo journals, bing journals, International Journal of Computational Engineering Research, Google journals, hard copy of Certificate,
journal of engineering, online Submission
Student information management system project report ii.pdfKamal Acharya
Our project explains about the student management. This project mainly explains the various actions related to student details. This project shows some ease in adding, editing and deleting the student details. It also provides a less time consuming process for viewing, adding, editing and deleting the marks of the students.
Welcome to WIPAC Monthly the magazine brought to you by the LinkedIn Group Water Industry Process Automation & Control.
In this month's edition, along with this month's industry news to celebrate the 13 years since the group was created we have articles including
A case study of the used of Advanced Process Control at the Wastewater Treatment works at Lleida in Spain
A look back on an article on smart wastewater networks in order to see how the industry has measured up in the interim around the adoption of Digital Transformation in the Water Industry.
Overview of the fundamental roles in Hydropower generation and the components involved in wider Electrical Engineering.
This paper presents the design and construction of hydroelectric dams from the hydrologist’s survey of the valley before construction, all aspects and involved disciplines, fluid dynamics, structural engineering, generation and mains frequency regulation to the very transmission of power through the network in the United Kingdom.
Author: Robbie Edward Sayers
Collaborators and co editors: Charlie Sims and Connor Healey.
(C) 2024 Robbie E. Sayers
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...Amil Baba Dawood bangali
Contact with Dawood Bhai Just call on +92322-6382012 and we'll help you. We'll solve all your problems within 12 to 24 hours and with 101% guarantee and with astrology systematic. If you want to take any personal or professional advice then also you can call us on +92322-6382012 , ONLINE LOVE PROBLEM & Other all types of Daily Life Problem's.Then CALL or WHATSAPP us on +92322-6382012 and Get all these problems solutions here by Amil Baba DAWOOD BANGALI
#vashikaranspecialist #astrologer #palmistry #amliyaat #taweez #manpasandshadi #horoscope #spiritual #lovelife #lovespell #marriagespell#aamilbabainpakistan #amilbabainkarachi #powerfullblackmagicspell #kalajadumantarspecialist #realamilbaba #AmilbabainPakistan #astrologerincanada #astrologerindubai #lovespellsmaster #kalajaduspecialist #lovespellsthatwork #aamilbabainlahore#blackmagicformarriage #aamilbaba #kalajadu #kalailam #taweez #wazifaexpert #jadumantar #vashikaranspecialist #astrologer #palmistry #amliyaat #taweez #manpasandshadi #horoscope #spiritual #lovelife #lovespell #marriagespell#aamilbabainpakistan #amilbabainkarachi #powerfullblackmagicspell #kalajadumantarspecialist #realamilbaba #AmilbabainPakistan #astrologerincanada #astrologerindubai #lovespellsmaster #kalajaduspecialist #lovespellsthatwork #aamilbabainlahore #blackmagicforlove #blackmagicformarriage #aamilbaba #kalajadu #kalailam #taweez #wazifaexpert #jadumantar #vashikaranspecialist #astrologer #palmistry #amliyaat #taweez #manpasandshadi #horoscope #spiritual #lovelife #lovespell #marriagespell#aamilbabainpakistan #amilbabainkarachi #powerfullblackmagicspell #kalajadumantarspecialist #realamilbaba #AmilbabainPakistan #astrologerincanada #astrologerindubai #lovespellsmaster #kalajaduspecialist #lovespellsthatwork #aamilbabainlahore #Amilbabainuk #amilbabainspain #amilbabaindubai #Amilbabainnorway #amilbabainkrachi #amilbabainlahore #amilbabaingujranwalan #amilbabainislamabad
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...Dr.Costas Sachpazis
Terzaghi's soil bearing capacity theory, developed by Karl Terzaghi, is a fundamental principle in geotechnical engineering used to determine the bearing capacity of shallow foundations. This theory provides a method to calculate the ultimate bearing capacity of soil, which is the maximum load per unit area that the soil can support without undergoing shear failure. The Calculation HTML Code included.
1. Final Project
Serial to Morse Code Converter
Engs 31: Digital Electronics
June 2020
Students:
Hana Ba-Sabaa
Sayuri Tais Miyamoto Magnabosco
Professor:
Geoffrey Luke
2. Abstract:
The Morse code is a method of communication using binary signals that encode text
characters as standardized sequences of two different signal durations, called dots and dashes.
The goal of this project is to create a serial to Morse code translator using VHDL code,
WaveForms software, AD2 board, and a Basys-3 FPGA integrated circuit board. Our system
is able to store up 100 characters of input, which can be released at any moment by the enter
key. In order to facilitate the design and validation of the Morse code converter system, we
followed top-down design and bottom-up implementation. Therefore, the functionality of the
system relies on the correct implementation of 8 small functional blocks: SCI Receiver, SCI
Transmitter, Check Character, Buffer,Morse Translator, Morse interpreter, Square Wave
Oscillator, and Final MUX. The SCI blocks receive the binary data coming from the AD2
block and concatenate them in ASCII formatting. The characters are then sent back to the
AD2 so the user can see on the screen their input. The SCIs work at a baud rate of 9,600
bits/sec. The Check Character block verifies if the enter key has been pressed to trigger the
translation of the bits in the system. The Buffer stores the characters inputted by the user,
while the translator transforms each bit into its Morse code equivalent – a representation of
dots (01) and dashes (11). The Interpreter uses such formatting as a time indicator for the
sound and light signals. The Square Wave Oscillator and Final MUX blocks take care of the
audio aspect of the system. They generate square waveforms with ideal frequencies to form
pitches recognizable to human ears (500Hz). The result of each component block is satisfying
and in alignment with the specifications for the whole system. Our design went through
synthesis, implementation and bitstream generation successfully. We also programmed our
board accordingly. However, during the demonstration, our board did not behave as expected.
We believe that the problem may have been with our wiring.
1
3. Table of Contents:
Introduction 3
Approach 4
System Design 4
Signal Generation and the AD2 Board 5
SCI Receiver 5
SCI Transmitter 7
Check Character 10
Buffer 10
Morse Translator 10
Morse interpreter 11
Square Wave Oscillator 13
Final MUX 13
Memory Map 13
Testing 13
Conclusions 33
Acknowledgements 33
Appendix (VHDL Code): 33
SCI Receiver 33
SCI Transmitter 45
Check Character 56
Buffer 58
Morse Translator 62
Morse Interpreter 67
Square Wave Oscillator 82
Final MUX 83
Final Top Code (Shell File) 84
2
4. Introduction
The device designed for this project is a Serial to Morse Code Converter. Using the
Serial Communications Interface (SCI), the user inputs characters into the system and the
device outputs the Morse code signal for it. The circuitry designed receives the character data
and converts it into an encoded format using binary signals. This step allows the read out of
the character in terms of dots and dashes, regulated by a precise timing. In this design, the
fundamental unit of time, 𝑇, is 0.1 s long.
The inputs of the circuitry are a 10MHz master clock and a 1 bit-signal coming from
the AD2 board. Each bit received from the AD2 board is stored in a shift register at a baud
rate of 9,600 bits/sec. The outputs of the system are a light and sound signal, a “full” signal
that lights up a LED when the user inputted 100 chracter, as well as a 1-bit signal that serially
transmits back to the AD2 the character originally inputted by the user. We also have an
end_tick to indicate when all the bits of the character were sent back to the AD2. This is
represented by the schematics below:
The system has a buffer that stores up to 100 characters. To have the message
decoded in sound and light format, the user must press enter and wait until all the characters
have been outputted to start writing again. If the user inputs 100 characters, the buffer gets
full and a LED lights up on the board to indicate that. In case the user keeps writing, the
characters will not be saved in the buffer and will be lost. To release the message stored, the
user must press the enter key. If the enter key is never pressed, then the “full” light will be
off. Our system converts both lower and upper case letters, and numbers 0-9. Any other
character will be recognized and outputted as zero.
3
5. Approach
In order to facilitate the design and validation of the morse code converter system, we
follow top-down design and bottom-up implementation. We broke down the system into the
following small components and built and tested each one of them individually:
1. Signal Generation and the AD2 Board
2. SCI Receiver
3. SCI Transmitter
4. Check Character
5. Buffer
6. Morse Translator
7. Morse interpreter
8. Square Wave Oscillator
9. Final MUX
For the components that needed a controller and a datapath, each part was designed and
tested separately using the EDAPlayground platform. Each component was then individually
wired and tested in Vivado for validation. After confirming that each part was matching the
design specifications, we built a shell and wired all the signals together in order to have a
working system.
Our team communicated daily and split the work accordingly. Components 2, 3, 7, and 8
were the main responsibility of Sayuri, while components 1, 4, 5, 6, and 9 were the main
responsibility of Hana. We would frequently meet and chat to discuss which signals were
needed in each component so our overall system would connect. Additionally, we helped
each other in code debugging and coordinated to attend TA hours together.
System Design
The following block diagram represents the overall architecture of the system:
4
6. 1. Signal Generation and the AD2 Board
In order to decide what letters the Morse code generator will make, the user sends
characters to the Basys3 board using the Serial Communications Interface (SCI). The SCI
signal is generated using the WaveForms software and the AD2 board, and sent to one
digital I/O pin on the Basys3. Each character entered is converted into the form of an 8-bit
ASCII character. Subsequently, the AD2 board outputs each bit of the character, one at a
time. This part does not require any VHDL design.
2. SCI Receiver
The SCI Receiver is a 10-bit shift register that takes in one bit at a time from the AD2
board, at the baud rate of 9,600 bits/sec, concatenates them into a single vector, removes the
start bit and stop bits, and shifts the 8-bit character result. The process is controlled by a state
machine. The receiver’s inputs are the serial data stream from the AD2 and a 10 MHz master
clock. Its outputs are the 8-bit data, in parallel, and a done_tick signal that goes high when the
output is ready. This is summarized by the following diagram:
5
7. a. Double Flop Synchronizer
Designed accordingly to the following schematics to provide an additional
clock period and resolve the metastability in the process.
b. Datapath
The serial data coming from the AD2 board is right-shifted into a 10-bit shift
register, called shift_reg, which is clocked by the 10 MHz clock, and enabled by a
signal shift_en from the controller. It has a shift_clr input for resetting. The bits 8
down to 1 of the shift register may be parallel-loaded out when enabled by the control
signal output_en.
c. Controller
The controller consists of a 6-state finite state machine and three counters, as
summarized in the diagram at the end of this section.
The “waiting” states were programmed to follow the baud rate of 9,600
bits/sec. In these states, the machine counts clock edges to locate the center of each
data bit. For the first bit, it counts N/2 clock edges, while for the remaining bits, it
counts up to N clock edges. Additionally, the machine relies on the counter that keeps
track of how many bits have been transmitted and stored in the shift register. When
there is the start bit + 9 other bits inside the register (count_shift=8), output_en goes
high so the datapath outputs the 8-bit ASCII character.
Each time the controller receives the start bit from the AD2 (data_in_sync =
0), it leaves its idle state and goes to its wait_start_bit state. In this state, shift_en goes
high and the start bit is stored in the shift register.
The machine stays in wait_start_bit state for half T (520 clock cycles, based
on the 10 MHz clk period) until count_half_T signal goes high; the machine then
moves to the shift_reg state. In shift_reg, the shift_en goes high and allows the bit
coming from the AD2 to be stored in the shift register. The machine then enters the
wait_other_bits state, where it waits for T (1042 clk cycles, based on the 10 MHz
clk), then count_T goes high and the machine returns to the shift_reg state to receive a
new bit.
After 10 bits of data have been put into the shift register, the machine moves
to shift_output state, where output_en goes high and the 8-bit ASCII code is parallely
shifted out of the register. Additionally, the output done_tick goes high to signal that
6
8. the ASCII data is available. Then, it goes to the clear state and returns to idle to wait
for the next start bit.
3. SCI Transmitter
The SCI Transmitter gets the 8-bit character signal from the SCI Transmitter and
sends it back to the AD2, in order to confirm to the user that the system is correctly storing
7
9. the character they input. Therefore, the transmitter works in reverse to the receiver; its inputs
are the 8-bit data, in parallel, and the done_tick signal from the SCI Receiver, indicating that
a new character is ready. Its outputs are ten 1-bit serial data at the same baud rate of 9,600
bits/sec, and an end_tick that goes high when the last bit of the character is sent to the AD2.
The transmitter consists of a 10-bit shift register that takes the 8-bit signal from the
receiver, concatenates it with a start and end bits (start = 0; end =1), and outputs one bit at a
time by left shifting the bits out of the register. This is summarized by the following diagram:
a. Double Flop Synchronizer
Designed to provide an additional clock period and resolve the metastability in
the process, following the schematics of the SCI Receiver flop synchronizer.
b. Datapath
The parallel data coming from the SCI Receiver is concatenated with a start
and end bit into a 10-bit register, which is clocked by the 10 MHz clock, and enabled
by a signal load_en from the controller. It has a reg_clr input for resetting. The bits
inside the shift register may be loaded out serially by right-shifting when enabled by
the control signal output_en.
c. Controller
The controller consists of a 5-state finite state machine and two counters, as
explained in the diagram below:
8
10. The wait_T state was programmed to follow the baud rate of 9,600 bits/sec. In
this state, the machine counts up to N clock edges before output-shifting each bit.
Another counter that regulates the state machine is the count_shift, which keeps track
of how many bits have been output back to the AD2.
Each time the controller receives the high signal of done_tick from the SCI
Receiver, it leaves its idle state and goes to its shift_load state. Here, load_en signal
goes high which allows the datapath to get the 8-bit data coming from the SCI
Receiver and concatenate it with a start and end bits into a 10-bit register. The
machine then moves to shift_nums state, where output_en goes high and triggers the
right-shifting out of a single bit. Subsequently, it goes to wait_T state, where it waits
9
11. for T (1042 clk cycles, based on the 10 MHz clk), then count_T goes high and the
machine returns to the shift_nums state to output another bit. After 10 bits of data
have been outputted (count_shift=9), the machine goes to the clear state, where
reg_clr and end_tick go high to signal that all the bits of that character have been
transmitted. Then, the controller returns to idle to wait for another character.
4. Check Character
This block checks whether the character coming from the SCI Receiver is an enter
key or not. If it is, the check_character block will output a signal, read_en, with a logic high,
which will later enable the buffer to read all the characters that have been previously stored in
the queue.
5. Buffer
The buffer is a 101 characters long 8-bit queue that stores the characters inputted by
the user until they press the enter key. When the user inputs 100 characters successfully , that
is they terminate their input with an enter key, a signal called ‘full’ (having a logic high) is
outputted by this buffer. This signal turns on an LED light on the board, which indicates to
the user that their input has been successfully saved in the queue.
The buffer is designed so that it only stores data in the queue both if a new character
is inputted by the user and there is space left in the queue. Therefore, if the user inputs 100
characters and forgets to press the enter key, their characters will not be stored in the queue
and, accordingly, their Morse code equivalent will never be outputted. To test our code, we
modified the queue so that it is 6 characters long.
6. Morse Translator
This block takes the data_out 8-bit signal
coming from the buffer and translates the ASCII that
the signal represents to its Morse code equivalent.
Using the table provided to us in the project handout,
we hard coded the Morse combination of dots and
dashes for each character (letters and numbers).
We represented dots with 01 and dashes with
11. Because the Morse code characters have different
lengths (the letter E is only a dot, while the number
zero is 5 dashes), our Morse code is 10-bits long, to
accommodate the longest characters. Accordingly, if
a character has less dots and dashes, 00 can be used
10
12. to pad it and ensure it is the same length as the other longer characters.
We also accounted for lowercase letters, which will translate to their uppercase Morse
code equivalents. In case a random character is inputted by the user, this block will output the
Morse code of a zero, i.e., 11 11 11 11 11.
7. Morse interpreter
This component receives the data coming from the translator and interprets the 01, 11,
and 00 bits of the data as a time indicator for the sound and light signals.
The speed of the Morse code is determined by a time T=0.1s. A dot is on for 𝑇 and
dash is on for 3𝑇. In between dots and dashes within a single letter there is a gap of 𝑇. In
between letters there is a gap of 3𝑇. In between words there is a gap of 7𝑇.
Its inputs are the 10-bit data from the translator, and translation_done tick that
indicates a new character was translated. It outputs signals for sound and light, and an
end_trans tick that goes high whenever the character is done being interpreted. This
component consists of a register and a controller. The register consists of a 10-bit shift
register that takes the 10-bit signal from the translator, reads and shifts the two left-most bits,
and outputs them as dots (01), dashes (11), or end of character (00). Intermediate signals
trigger the state machine and the datapath as demonstrated in the diagram below:
a. Datapath
The parallel data coming from the Translator is put into the register, which is clocked
by the 10 MHz clock, and enabled by a signal load_en from the controller. If the
character is a space (all zeros), then the register sends the signal space to the
controller; otherwise, it sends the signal no_space. Triggered by the signal
check_bits_en from the controller, the datapath analyzes the bits 9 down to 8 of the
register; if they are 01, it outputs the signal dot as high; if they are 11, it outputs dash
as high; if they are 00; it outputs end_char as high. The signal shift_en triggers the
left-shift of the two left-most bits of the register, so the next two bits can be decoded.
The signals count_T_en, count_3T_en, and count_7T_en, dictate when light and
11
13. sound signals will be high or low and for how long, following the speed of the Morse
code of T=0.1s.
b. Controller
The controller consists of a 10-state finite state machine and several counters to mark
the time for dots and dashes for each character, as explained in the diagram below:
The “timing” states were programmed to follow the speed of the morse code
as T=0.1s. In these states, the machine counts clock edges up to T, 3T, or 7T.
Each time the translator has a new character available, (translation_done = 1),
it leaves its idle state and goes to its shift_register state. In this state, load_en goes
high so the data from the translator is stored in the register in the datapath. If the
character we receive is a space, space=1 and we move to time_7T state. The machine
stays in this state for 0.7s until count_7T_TC goes high and the machine moves to the
clear state.
However, if the data received is not a space character, not_space=1, and the
machine moves to check_bits state. Here, check_bits_en goes high and we receive
back from the datapath the information of whether we have a dot, a dash, or the
end_char.
12
14. A. If dash=1, we move to time_3T state. We stay in this state for 0.3s,
held by a counter. When count_3T_TC = 1, we move to
time_within_letters state.
B. If dot=1, we move to time_T state. We stay in this state for 0.1s, held
by a counter. When count_T_TC = 1, we move to time_within_letters
state.
C. If end_char=1, we move to time_between_letters state. We stay here
for 0.3s. Then count_between_letters_TC goes high and we move to
the clear state.
In the time_within_letters state, the signal count_within_char_en=1, which
triggers the count of clk cycles up to 0.3s. Then, the terminal count goes high and we
move to the shift_bits state. Here, the signal shift_en goes high and allows for the bis
in the shift register in the datapath to shift left and expose the next encoded morse
signal. Then, the machine goes back to check_bits state to verify the presence of dot,
dash, or end of character bits.
Once in the clear state, end_trans goes high to indicate we are done outputting
the morse for that character. Then it returns to idle to wait for the next character.
8. Square Wave Oscillator
This component creates a square wave to output the sound at a frequency of 500Hz,
which is an audible range for human beings. Its input is the master clock at 10MHz and its
output is the sound_wave. The sound_wave stays high for 2000 clk cycles.
9. Final MUX
This component “AND” the sound_wave signal from the Square Wave Oscillator and
the sound signal coming out of the Morse interpreter, so we only have audible sound while
the sound signal is high.
Memory Map
In this design, we used 4 10-bit registers for the SCI receiver and transmitter. For the
queue, we had to have enough memory to store 8bits *100. For the translator, we used
enough memory to encode a 10-bit representation for each character. The following graphs
summarize the post-implementation memory data for our circuitry:
13
15. Testing
1. Components
When testing each component, we addressed each error and warning message
received, to make sure they would not be a major issue when assembling the whole
system.
a. Signal Generation and the AD2 Board
We connected the receiver and transmitter of the AD2 Board. Below is a
screenshot of our waveform for ‘hello world’.
b. SCI Receiver
14
36. Conclusions
Each component of our project successfully meets the requirements specified in the
introduction. When wired together, all the blocks were successfully implemented into the
Basys3 board as well. However, the board did not behave as expected. Both the LEDs for the
Morse code light and for the “full” buffer signal were always on, and no sound was coming
out of the WaveForm software. Because we did not get any error messages through our
implementation and each separate component was behaving as expected, we believe that the
issue was with wiring the board with the AD2 component.
If we were to design this project again, we would modify the code for the buffer, so
the “full” signal for the LED lights up when the user has input 100 chracters and stays on
until the input is the enter key. Another modification would be to combine the block “Square
Wave Oscillator” and “Final MUX”, since they both deal with the sound output of the Morse
code. Additionally, we would also include a clock divider on our top shell to slow down the
Basys board clock. We would keep our top-down design and bottom-up implementation, as
we believe it is a good approach to debugging and testing.
Acknowledgements
Throughout the project, we referred back to the projects we built in the lab sections
for guidance on how to break down our system in small components and follow top-down
design and bottom-up implementation. We referred to the slides provided by Professor Luke
to set up the parameters for the WaveForms software and for connecting the Basys3 and the
AD2 component. These slides also guided us to connect the Morse code sound_out to the
oscilloscope to play the sound. The buffer was built upon the code we wrote for this year’s
“Exercise 19: Queues”. The SCI Receiver and SCI transmitter were designed by adapting the
instructions of Lab5 of Spring 2016. The XDC file provided in this year’s Lab 4 was used as
a template to generate our own constraints.
We would like to acknowledge the help of TAs Ruthie, Matthew, and Shailin, for
their guidance and support throughout the project. We are also grateful for our classmates
Akwasi and Tyler, who kept us company throughout this project and made sure we always
had fun music playing in Mclaughlin’s common room.
Appendix (VHDL Code):
1. SCI Receiver
a. Double-Flop Synchronizer
i. Code
-- Code your design here
library IEEE;
use IEEE.std_logic_1164.all;
35
37. ENTITY SCI_receiver_double_flop IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_in : in STD_LOGIC; -- 1bit signal from AD2
data_sync : out STD_LOGIC); -- 1bit signal after being delayed
by 2 clk cycles
end SCI_receiver_double_flop;
architecture behavior of SCI_receiver_double_flop is
--Signals
signal d_in_sync, dsync : std_logic :='0'; -- signals for double flop
synchronizer
BEGIN
-- Double-flop synchronizer
double_flop_sync: process (clk)
begin
if rising_edge(clk) then
dsync <= data_in; -- flop 1
data_sync <= dsync; -- flop 2
end if;
end process;
end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
entity SCI_receiver_double_flop_tb is
end SCI_receiver_double_flop_tb;
architecture testbench of SCI_receiver_double_flop_tb is
component SCI_receiver_double_flop
PORT ( clk : in STD_LOGIC; --10MHz clock
data_in : in STD_LOGIC; -- 1bit signal from AD2
data_sync : out STD_LOGIC); -- 1bit signal after being delayed
by 2 clk cycles
end component;
-- signals
signal clk, data_in, data_sync: std_logic := '0';
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut : SCI_receiver_double_flop PORT MAP(
36
38. clk => clk,
data_in=> data_in,
data_sync=> data_sync);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
wait for 1*clk_period;
data_in<='1';
wait for 1*clk_period;
data_in<='0';
wait for 1*clk_period;
data_in<='1';
wait for 1*clk_period;
data_in<='0';
wait for 1*clk_period;
data_in<='1';
wait for 1*clk_period;
data_in<='0';
wait for 1*clk_period;
data_in<='1';
wait for 1*clk_period;
data_in<='0';
wait for 1*clk_period;
end process;
end testbench;
b. Controller
i. code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY SCI_receiver_controller IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync: in STD_LOGIC; -- 1bit signal from double flop
synchronizer
shift_en : out STD_LOGIC; -- send to datapath
shift_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
done_tick : out STD_LOGIC); -- indicates new data is ready
end SCI_receiver_controller;
37
39. architecture behavior of SCI_receiver_controller is
--signals
type state_type is (idle, wait_start_bit, wait_other_bits, shift_reg,
shift_output, clear); -- states of FSM
signal current_state, next_state : state_type := idle;
signal count_halfT, count_T, count_halfT_en, count_T_en,output_en_signal,
shift_en_signal: std_logic:= '0';
signal count_shift,count_clk_cycles, count_Tclk_cycles: integer:=0;
BEGIN
-- update state machine states
stateUpdate: process(clk)
BEGIN
if rising_edge(clk) then
current_state <= next_state;
end if;
end process stateUpdate;
-- controller
controller: process (current_state,count_halfT, count_T, data_sync,
count_shift)
begin
output_en_signal <= '0';
shift_en_signal <='0';
case (current_state) is
when idle=>
shift_clr<='0';
shift_en<='0';
output_en<='0';
done_tick<='0';
count_halfT_en<='0';
count_T_en <='0';
if data_sync='0' then -- receives start bit
next_state<=wait_start_bit;
end if;
when wait_start_bit=>
shift_clr<='0';
shift_en<='0';
output_en<='0';
done_tick<='0';
count_halfT_en<='1';
count_T_en <='0';
if count_halfT='1' then -- after waited T/2
next_state<=shift_reg;
end if;
38
40. when wait_other_bits=>
shift_clr<='0';
shift_en<='0';
output_en<='0';
done_tick<='0';
count_halfT_en<='1';
count_T_en <='1';
if count_T='1' then -- after waited T
next_state<=shift_reg;
end if;
when shift_reg=>
shift_clr<='0';
shift_en<='1';
shift_en_signal<='1';
output_en<='0';
done_tick<='0';
count_halfT_en<='1';
count_T_en <='1';
if count_shift = 8 then -- if already input 9 bits
next_state<=shift_output;
else
next_state<=wait_other_bits;
end if;
when shift_output=>
shift_clr<='0';
shift_en<='0';
output_en<='1';
output_en_signal<='1';
done_tick<='1';
count_halfT_en<='0';
count_T_en <='0';
next_state<=clear;
when clear=>
shift_clr<='1'; -- clear shift register
shift_en<='0';
output_en<='0';
done_tick<='0';
count_halfT_en<='0';
count_T_en <='0';
next_state<=idle;
end case;
end process;
-- time we need to wait after receiving 1 bit so it matches a baud rate of
9600
half_time: process (clk, count_halfT_en)
begin
39
41. if rising_edge (clk) then
if count_halfT_en='1' then
count_clk_cycles <= count_clk_cycles+1;
if count_clk_cycles = 520 then -- num of clk cycles to count for T/2,
based on a 10Mhz clk period
count_halfT <= '1'; -- flags that T/2 has passed; T/2 = (1/2) *
(1/9600)
else
count_halfT<='0';
end if;
if count_clk_cycles = 1041 then -- num of clk cycles (1042 clck cycles)
to count for T, based on a 10Mhz clk period
count_clk_cycles <=0; -- resets counter after reaching 1042 clock
cycles
end if;
end if;
end if;
end process;
-- time we need to wait after receiving other bits so it matches a baud rate
of 9600
full_time: process (clk, count_T_en)
begin
if rising_edge (clk) then
if count_T_en='1' then
count_Tclk_cycles <= count_Tclk_cycles+1;
if count_Tclk_cycles = 1041 then -- num of clk cycles (1042 clck
cycles) to count for T, based on a 10Mhz clk period
count_T<='1'; -- flags that T has passed; T = 1/9600
count_Tclk_cycles <=0; -- resets counter after reaching 208 clock
cycles
else
count_T<='0';
end if;
end if;
end if;
end process;
-- counting the numb of bits in the shift register
bit_count: process (clk, shift_en_signal, output_en_signal)
begin
if rising_edge(clk) then
if shift_en_signal='1' then -- in shift state
count_shift<=count_shift+1;
end if;
if output_en_signal ='1' then -- indicates we have 9 bits of data
count_shift<=0;
end if;
end if;
40
42. end process;
end behavior;
-- Math for T and T/2:
--T<= 1/9600; -- T for the baud rate in seconds
--num_clk_cycles <= T/(100*10^-9); -- for 2MHz clock
-- 1042 num_clk cycles (rounded up)
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity SCI_receiver_controller_tb is
end SCI_receiver_controller_tb;
architecture testbench of SCI_receiver_controller_tb is
component SCI_receiver_controller
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync: in STD_LOGIC; -- 1bit signal from double flop
synchronizer
shift_en : out STD_LOGIC; -- send to datapath
shift_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
done_tick : out STD_LOGIC);
end component;
-- signals
signal clk, shift_en, shift_clr, output_en, done_tick: std_logic := '0';
signal data_sync: std_logic:= '1';
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut : SCI_receiver_controller PORT MAP(
clk => clk,
data_sync=> data_sync,
shift_en=> shift_en,
shift_clr=>shift_clr,
output_en=>output_en,
done_tick=>done_tick);
41
43. clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
wait for 5*clk_period;
data_sync<='0'; -- receives start bit
wait for 1042*clk_period;
data_sync<='1';
wait for 1042*clk_period;
data_sync<='0';
wait for 1042*clk_period;
data_sync<='1';
wait for 1042*clk_period;
data_sync<='0';
wait for 1042*clk_period;
data_sync<='1';
wait for 1042*clk_period;
data_sync<='0';
wait for 1042*clk_period;
data_sync<='1';
wait for 1042*clk_period;
data_sync<='0';
wait for 1042*clk_period;
data_sync<='1';
wait for 1042*clk_period;
wait for 400*clk_period;
end process;
end testbench;
c. Datapath
i. code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY SCI_receiver_datapath IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync : in STD_LOGIC; -- 1bit signal from flop
synchronizer
42
44. shift_en : in STD_LOGIC; -- receiveing from controller
shift_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
data_out : out STD_LOGIC_VECTOR(7 downto 0));-- 8 bits of
parallel data
end SCI_receiver_datapath;
architecture behavior of SCI_receiver_datapath is
--Signals
signal shift_reg: std_logic_vector(9 downto 0):= (others=>'0');-- holds 10
bits
BEGIN
-- Shift and output registers
registers: process (clk, output_en, shift_en, shift_clr)
begin
if rising_edge(clk) then
if shift_clr ='1' then -- clears what is inside the shift register
shift_reg<="0000000000";
elsif shift_clr ='0' then -- if doesn't want to clear the register
if shift_en='1' then -- shift right; most significant bit of
the register gets what is on d_in_sync (the bit coming from AD2 and delayed
by the double-flop)
shift_reg <= data_sync & shift_reg(9 downto 1);
end if;
if output_en ='1' then -- when load register is enabled
data_out <= shift_reg(8 downto 1); -- does not copy start and
end bit
end if;
end if;
end if;
end process;
end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity SCI_receiver_datapath_tb is
end SCI_receiver_datapath_tb;
architecture testbench of SCI_receiver_datapath_tb is
43
45. component SCI_receiver_datapath
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync : in STD_LOGIC; -- 1bit signal from flop
synchronizer
shift_en : in STD_LOGIC; -- receiveing from controller
shift_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
data_out : out STD_LOGIC_VECTOR(7 downto 0));
end component;
-- signals
signal clk, data_sync, shift_en, shift_clr, output_en: std_logic := '0';
signal data_out: std_logic_vector(7 downto 0) := (others=>'0');
constant clk_period: time := 100ns; --10MHz clock
begin
uut : SCI_receiver_datapath PORT MAP(
clk => clk,
data_sync=> data_sync,
shift_en=> shift_en,
shift_clr=>shift_clr,
output_en=>output_en,
data_out=>data_out);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
shift_en<='1'; -- allows shift register to receive the data
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
data_sync<='0';
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
data_sync<='0';
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
data_sync<='0';
wait for 1*clk_period;
44
46. data_sync<='1';
wait for 1*clk_period;
data_sync<='0';
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
-- shift register must be 101010101 in the end
shift_en<='0';
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
data_sync<='1';
wait for 1*clk_period;
-- tries adding 11, but shift enable signal is not on, so shift register must
keep its value
output_en<='1'; -- output what is on the shift register
wait for 1*clk_period;
shift_clr<='1'; -- clears the shift register
wait for 1*clk_period;
wait;
end process;
end testbench;
d. Shell
i. code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SCI_Receiver_top is
Port ( clk : in STD_LOGIC;
data_in : in STD_LOGIC; -- 1bit signal from AD2;
done_tick: out STD_LOGIC;
data_out : out STD_LOGIC_VECTOR(7 downto 0));-- 8 bits of
parallel data
end SCI_Receiver_top;
architecture Behavioral of SCI_Receiver_top is
component SCI_receiver_controller IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync: in STD_LOGIC; -- 1bit signal from double flop
synchronizer
shift_en : out STD_LOGIC; -- send to datapath
shift_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
done_tick : out STD_LOGIC); -- indicates new data is ready
end component;
45
47. component SCI_receiver_datapath IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_sync : in STD_LOGIC; -- 1bit signal from flop
synchronizer
shift_en : in STD_LOGIC; -- receiveing from controller
shift_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
data_out : out STD_LOGIC_VECTOR(7 downto 0));-- 8 bits of
parallel data
end component;
component SCI_receiver_double_flop IS
PORT ( clk : in STD_LOGIC; --10MHz clock
data_in : in STD_LOGIC; -- 1bit signal from AD2
data_sync : out STD_LOGIC); -- 1bit signal after being delayed
by 2 clk cycles
end component;
signal shift_en,shift_clr,output_en: STD_LOGIC :='0';
signal data_sync: STD_LOGIC :='1';
begin
uut : SCI_receiver_controller
port map ( clk => clk, --10MHz clock
data_sync => data_sync, -- 1bit signal from double flop
synchronizer
shift_en => shift_en, -- send to datapath
shift_clr => shift_clr, -- send to datapath
output_en => output_en, -- send to datapath
done_tick => done_tick); -- indicates new data is ready
uut2: SCI_receiver_datapath
port map ( clk => clk, --10MHz clock
data_sync => data_sync, -- 1bit signal from flop synchronizer
shift_en => shift_en, -- receiveing from controller
shift_clr => shift_clr, -- receiveing from controller
output_en => output_en, -- receiveing from controller
data_out => data_out);-- 8 bits of parallel data
uut3: SCI_receiver_double_flop
port map ( clk => clk, --10MHz clock
data_in => data_in, -- 1bit signal from AD2
data_sync => data_sync); -- 1bit signal after being delayed by 2
clk cycles
end Behavioral;
46
48. 2. SCI Transmitter
a. Double-Flop Synchronizer
i. code
-- Code your design here
library IEEE;
use IEEE.std_logic_1164.all;
library IEEE;
use IEEE.std_logic_1164.all;
ENTITY SCI_transmitter_double_flop IS
PORT ( clk : in STD_LOGIC; --10MHz clock
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0); -- 8bit
signal from SCI receiver
receiver_data_sync :out STD_LOGIC_VECTOR(7 DOWNTO 0)); -- 8bit
signal after being delayed by 2 clk cycles
end SCI_transmitter_double_flop;
architecture behavior of SCI_transmitter_double_flop is
--Signals
signal dsync : std_logic_vector(7 downto 0) :="00000000"; -- signals for
double flop synchronizer
BEGIN
-- Double-flop synchronizer
double_flop_sync: process (clk)
begin
if rising_edge(clk) then
dsync <= receiver_data; -- flop 1
receiver_data_sync <= dsync; -- flop 2
end if;
end process;
end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
entity SCI_transmitter_double_flop_tb is
end SCI_transmitter_double_flop_tb;
architecture testbench of SCI_transmitter_double_flop_tb is
component SCI_transmitter_double_flop
47
49. PORT ( clk : in STD_LOGIC; --10MHz clock
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0); -- 8bit
signal from SCI receiver
receiver_data_sync :out STD_LOGIC_VECTOR(7 DOWNTO 0)); -- 8bit
signal after being delayed by 2 clk cycles
end component;
-- signals
signal receiver_data, receiver_data_sync: std_logic_vector(7 downto 0) :=
"00000000";
signal clk : std_logic :='0';
constant clk_period: time := 100ns; --10MHz clock
begin
uut : SCI_transmitter_double_flop PORT MAP(
clk=> clk,
receiver_data=> receiver_data,
receiver_data_sync=> receiver_data_sync);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
wait for 1*clk_period;
receiver_data<="11111111";
wait for 1*clk_period;
receiver_data<="10101010";
wait for 1*clk_period;
end process;
end testbench;
b. Controller
i. code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY SCI_transmitter_controller IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
48
50. data_in_sync : in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from flop synchronizer
done_tick : in STD_LOGIC; -- from controller of receiver; indicates
that new 8bit data is ready
load_en : out STD_LOGIC; -- send to datapath
reg_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
end_tick : out STD_LOGIC);-- indicates finished passing the
data to AD2
end SCI_transmitter_controller;
architecture behavior of SCI_transmitter_controller is
--Signals
type state_type is (idle, wait_T, shift_load, shift_nums, clear); -- states
of FSM
signal current_state, next_state : state_type := idle;
signal count_halfT, count_T, count_T_en,end_tick_signal, output_en_signal:
std_logic:= '0';
signal count_shift, count_Tclk_cycles: integer:=0;
BEGIN
-- update state machine states
stateUpdate: process(clk)
BEGIN
if rising_edge(clk) then
current_state <= next_state;
end if;
end process stateUpdate;
-- controller
controller: process (current_state, done_tick, count_shift, count_T)
begin
-- defaults; will only change inside the states
load_en<='0';
reg_clr<='0';
output_en<='0';
end_tick<='0';
count_T_en <='0';
output_en_signal<='0';
case (current_state) is
when idle=>
if done_tick='1' then -- ready to receive new bits
next_state<=shift_load;
end if;
49
51. when shift_load=>
load_en<='1'; -- data goes to shift register
next_state<=shift_nums;
when shift_nums=>
output_en<='1';-- allows numbers to get shifted out
output_en_signal<='1';
if count_shift = 9 then -- after shifting 10 bits of data
next_state<= clear;
else
next_state<= wait_T;
end if;
when wait_T=>
count_T_en <='1';
if count_T='1' then -- after waited T
next_state<=shift_nums;
end if;
when clear=>
end_tick<='1'; -- indicates that finished shifitng data out
end_tick_signal<='1';
reg_clr<='1'; -- clear register
next_state<=idle;
end case;
end process;
-- count how many bits have been output
bit_count: process (clk, output_en_signal, end_tick_signal)
begin
if rising_edge(clk) then
if output_en_signal='1' then -- in shift state
count_shift<=count_shift+1;
end if;
if end_tick_signal ='1' then -- indicates we have 10 bits of data
count_shift<=0;
end if;
end if;
end process;
-- counter for baud rate
time_T: process (clk, count_T_en)
begin
if rising_edge (clk) then
if count_T_en='1' then
count_Tclk_cycles <= count_Tclk_cycles+1;
if count_Tclk_cycles = 1041 then -- num of clk cycles (1042 clck
cycles) to count for T, based on a 10Mhz clk period
count_T<='1'; -- flags that T has passed; T = 1/9600
50
52. count_Tclk_cycles <=0; -- resets counter after reaching 1042
clock cycles
else
count_T<='0';
end if;
end if;
end if;
end process;
end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity SCI_transmitter_controller_tb is
end SCI_transmitter_controller_tb;
architecture testbench of SCI_transmitter_controller_tb is
component SCI_transmitter_controller
PORT ( clk : in STD_LOGIC; --10 MHz clock
data_in_sync : in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from flop synchronizer
done_tick : in STD_LOGIC; -- from controller of receiver; indicates
that new 8bit data is ready
load_en : out STD_LOGIC; -- send to datapath
reg_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
end_tick : out STD_LOGIC);-- indicates finished passing the
data to AD2
end component;
-- signals
signal clk, done_tick, load_en, reg_clr, output_en, end_tick: std_logic :=
'0';
signal data_in_sync: std_logic_vector(7 downto 0):= "00000000";
constant clk_period: time := 100ns; --10 MHz clock
begin
uut : SCI_transmitter_controller PORT MAP(
51
53. clk => clk,
data_in_sync=> data_in_sync,
done_tick=> done_tick,
load_en=> load_en,
reg_clr=>reg_clr,
output_en=>output_en,
end_tick=>end_tick);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
wait for 5*clk_period;
done_tick<='1'; -- receives new data
wait for 1*clk_period;
done_tick<='0';
wait for 1*clk_period;
data_in_sync<="10101010";
wait for 10420*clk_period;
wait for 400*clk_period;
end process;
end testbench;
c. Datapath
i. Code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY SCI_transmitter_datapath IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
data_in_sync : in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from flop synchronizer
load_en : in STD_LOGIC; -- receiveing from controller
reg_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
transmitter_data_out : out STD_LOGIC);-- 1 bit signal to AD2
52
54. end SCI_transmitter_datapath;
architecture behavior of SCI_transmitter_datapath is
--Signals
signal shift_reg: std_logic_vector(9 downto 0):= (others=>'0');-- holds 10
bits of data
signal fill_reg: std_logic:= '0'; -- used to left shift bits out of the
register
signal start_bit: std_logic:='0'; -- start bit to be added to the signal for
each letter
signal end_bit: std_logic:='1'; -- end bit to be added to the signal for each
letter
BEGIN
-- Shift and output registers
registers: process (clk, output_en, load_en, reg_clr)
begin
if rising_edge(clk) then
if reg_clr ='1' then -- clears what is inside the shift register
shift_reg<="0000000000";
elsif reg_clr ='0' then -- if doesn't want to clear the register
if load_en='1' then -- shift register gets the value of the
data coming in (the 8-bits coming from SCI transmitter and delayed by the
double-flop)
shift_reg <= (start_bit)&(data_in_sync)&(end_bit); -- adds
start and end bit and save value in a shift register
else
shift_reg<= shift_reg; -- shift reg hold its current value
end if;
if output_en ='1' then -- when load register is enabled
transmitter_data_out <= shift_reg(9); -- outputs first bit of
data
shift_reg<= shift_reg(8 downto 0)&fill_reg; -- left shifting
the bits out of the register
end if;
end if;
end if;
end process;
end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
53
55. use IEEE.numeric_std.all;
entity SCI_transmitter_datapath_tb is
end SCI_transmitter_datapath_tb;
architecture testbench of SCI_transmitter_datapath_tb is
component SCI_transmitter_datapath
PORT ( clk : in STD_LOGIC; --10 MHz clock
data_in_sync: in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from SCI receiver
load_en : in STD_LOGIC; -- receiveing from controller
reg_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
data_out : out STD_LOGIC);-- 1 bit signal to AD2
end component;
-- signals
signal clk, data_out, load_en, reg_clr, output_en: std_logic := '0';
signal data_in_sync: std_logic_vector(7 downto 0) := (others=>'0');
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut : SCI_transmitter_datapath PORT MAP(
clk => clk,
data_in_sync=> data_in_sync,
load_en=> load_en,
reg_clr=> reg_clr,
output_en=>output_en,
data_out=>data_out);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
load_en<='1'; -- allows shift register to receive the data
wait for 1*clk_period;
data_in_sync<="11111111";
wait for 1*clk_period;
load_en<='0';
wait for 1*clk_period;
54
56. reg_clr<='1'; -- clears the shift register
wait for 1*clk_period;
reg_clr<='0';
wait for 1*clk_period;
data_in_sync<="10101010";
wait for 1*clk_period;
load_en<='1'; -- allows shift register to receive the data
wait for 1*clk_period;
-- shift register must be 11001100
load_en<='0'; -- cannot receive data anymore
wait for 1*clk_period;
data_in_sync<="11111111";
wait for 1*clk_period;
-- tries adding new value, but shift enable signal is not on, so shift
register must keep its value
output_en<='1'; -- output what is on the shift register
wait for 8*clk_period;
output_en<='0';
wait for 1*clk_period;
end process;
end testbench;
d. Shell
i. code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SCI_Transmitter_top is
Port ( clk : in STD_LOGIC;
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0);
done_tick: in std_logic;
transmitter_data_out : out STD_LOGIC;-- 1 bit signal to AD2
end_tick : out STD_LOGIC);-- indicates finished passing the
data to AD2
end SCI_Transmitter_top;
architecture Behavioral of SCI_Transmitter_top is
component SCI_transmitter_controller IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
data_in_sync : in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from flop synchronizer
done_tick : in STD_LOGIC; -- from controller of receiver; indicates
that new 8bit data is ready
load_en : out STD_LOGIC; -- send to datapath
reg_clr : out STD_LOGIC; -- send to datapath
output_en : out STD_LOGIC; -- send to datapath
55
57. end_tick : out STD_LOGIC);-- indicates finished passing the
data to AD2
end component;
component SCI_transmitter_datapath IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
data_in_sync : in STD_LOGIC_VECTOR(7 downto 0); -- 8bit signal
(parallel data) from flop synchronizer
load_en : in STD_LOGIC; -- receiveing from controller
reg_clr : in STD_LOGIC; -- receiveing from controller
output_en : in STD_LOGIC; -- receiveing from controller
transmitter_data_out : out STD_LOGIC);-- 1 bit signal to AD2
end component;
component SCI_transmitter_double_flop IS
PORT ( clk : in STD_LOGIC; --10MHz clock
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0); -- 8bit
signal from SCI receiver
receiver_data_sync :out STD_LOGIC_VECTOR(7 DOWNTO 0)); -- 8bit
signal after being delayed by 2 clk cycles
end component;
signal load_en,reg_clr,output_en: STD_LOGIC :='0';
signal data_in_sync,receiver_data_sync :std_logic_vector(7 downto
0):=(others=>'0');
begin
uut4 : SCI_Transmitter_controller
port map( clk=>clk, --10 MHz clock
data_in_sync =>receiver_data, -- 8bit signal (parallel data)
from flop synchronizer
done_tick =>done_tick , -- from controller of receiver; indicates
that new 8bit data is ready
load_en=>load_en, -- send to datapath
reg_clr=>reg_clr, -- send to datapath
output_en=>output_en, -- send to datapath
end_tick =>end_tick);-- indicates finished passing the data to
AD2
uut5: SCI_Transmitter_datapath
port map ( clk => clk, --10 MHz clock
data_in_sync => receiver_data, -- 8bit signal (parallel data)
from flop synchronizer
load_en =>load_en, -- receiveing from controller
reg_clr =>reg_clr, -- receiveing from controller
output_en =>output_en, -- receiveing from controller
transmitter_data_out =>transmitter_data_out);-- 1 bit signal to
AD2
uut3: SCI_Transmitter_double_flop
port map ( clk => clk, --10MHz clock
56
58. receiver_data =>receiver_data, -- 8bit signal from SCI receiver
receiver_data_sync=>receiver_data_sync); -- 8bit signal after
being delayed by 2 clk cycles
end Behavioral;
ii. testbench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity SCI_Transmitter_top_tb is
end SCI_Transmitter_top_tb;
architecture Testbench of SCI_Transmitter_top_tb is
component SCI_Transmitter_top is
Port ( clk : in STD_LOGIC;
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0);
done_tick: in std_logic;
transmitter_data_out : out STD_LOGIC;-- 1 bit signal to AD2
end_tick : out STD_LOGIC);-- indicates finished passing the
data to AD2
end component;
signal clk : std_logic := '0';
signal transmitter_data_out, done_tick : std_logic:= '0';
signal receiver_data: std_logic_vector(7 downto 0):= (others => '0');
signal end_tick :std_logic :='0';
constant clk_period : time := 100ns; -- 10 MHz clock
-- Data definitions
BEGIN
uut00: SCI_Transmitter_top
port map ( clk => clk,
receiver_data=> receiver_data,-- 1bit signal from AD2;
done_tick=> done_tick,
end_tick => end_tick,
transmitter_data_out => transmitter_data_out);-- 8 bits of
parallel data
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
begin
57
59. done_tick<='1';
receiver_data<="01010100";
wait for 1*clk_period;
done_tick<='0';
wait for 10420*clk_period;
done_tick<='1';
receiver_data<="00000000";
wait for 1*clk_period;
done_tick<='0';
wait for 10420*clk_period;
done_tick<='1';
receiver_data<="10010001";
wait for 1*clk_period;
done_tick<='0';
wait for 10420*clk_period;
wait for 400*clk_period;
end process;
end Testbench;
3. Check Character
i. code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY check_character IS
PORT ( clk : in STD_LOGIC; --2MHz master clock
Data_in_receiver : in STD_LOGIC_VECTOR(7 downto
0); --from sci receiver
read_en : out std_logic);
end check_character;
architecture behaviour of check_character is
begin
process(clk)
BEGIN
read_en<='0';
if rising_edge(clk) then
if Data_in_receiver="00001010" then --ascii code of enter
read_en<='1';
else
read_en<='0';
end if ;
58
60. end if;
end process;
end behaviour;
ii. testbench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity check_character_tb is
end check_character_tb ;
architecture testbench of check_character_tb is
component check_character is
PORT (clk : in STD_LOGIC; --10MHz master clock
Data_in_receiver : in STD_LOGIC_VECTOR(7 downto
0);
read_en : out std_logic);
end component;
signal clk: std_logic;
signal Data_in_receiver : std_logic_vector(7 downto 0):="00000000" ;
signal read_en : std_logic := '0';
begin
uut : check_character PORT MAP(
clk => clk,
Data_in_receiver => Data_in_receiver,
read_en => read_en);
clk_proc : process
BEGIN
CLK <= '0';
wait for 5ns;
CLK <= '1';
wait for 5ns;
end process clk_proc;
stim_proc : process
begin
Data_in_receiver <= "11110000";
wait for 8 ns;
Data_in_receiver <= "00001111";
wait for 8 ns;
59
61. Data_in_receiver <= "10101010";
wait for 8 ns;
Data_in_receiver <="00001010";
wait for 8 ns;
Data_in_receiver <= "01010101";
wait for 8 ns;
Data_in_receiver <= "11110000";
wait for 8 ns;
Data_in_receiver <= "00001111";
wait for 8 ns;
Data_in_receiver <= "10101010";
wait for 8 ns;
Data_in_receiver <="00101010";
wait for 8 ns;
Data_in_receiver <= "01010101";
wait for 8 ns;
end process stim_proc;
end testbench;
4. Buffer
i. code
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY Queue IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
Write_en : in STD_LOGIC; --input character
read_en : in STD_LOGIC; --enter pressed
done_translating: in std_logic; --Done translating a character
to input a new one
Data_in_Q : in STD_LOGIC_VECTOR(7 downto 0);
Data_out_Q: out STD_LOGIC_VECTOR(7 downto 0);
full: out std_logic);
end Queue;
architecture behavior of Queue is
60
62. type regfile is array(0 to 100) of STD_LOGIC_VECTOR(7 downto 0);
signal Queue_reg : regfile;
signal W_ADDR : integer := 0;
signal R_ADDR : integer := 0;
signal used,count: integer := 0;
signal full_sig : std_logic;
constant threshold: integer := 101;
BEGIN
process(clk,write_en,read_en,data_in_Q,done_translating)
begin
if rising_edge(clk) then
if (Write_en = '1') and read_en='0' then --if a new character
is inputted
if (full_sig = '0') then --if the queue is not full
Queue_reg(W_ADDR) <= Data_in_Q; --stores data in the
queue
used<=used+1;
count<=count+1;
if W_ADDR =threshold-1 then --if the queue is full and we
can no longer write, reset the address back to zero
W_ADDR <= 0;
used<=0;
count<=0;
else
W_ADDR <= W_ADDR + 1; --otherwise, increment the address
to store data in the queue
end if;
end if;
end if;
if (read_en = '1') then -- if enter is pressed
if done_translating='1' then --and if the previous
charcter is already transalted by the interpreter to its morse code
Queue_reg(R_ADDR) <= (others => '0'); --after it
reads whatever is in the address, it resets it back to zero
used<=used-1; -- and decrement the number of used
levels by one
if R_ADDR = threshold-1 then
R_ADDR <= 0;
used<=0;
else
R_ADDR <= R_ADDR + 1;
end if;
end if;
end if;
end if;
61
63. Data_out_Q <= Queue_reg(R_ADDR); --the queue is reading the stored
data and outputting it
end process;
full_proc: process(count,clk)
begin
if rising_edge(clk) then
if count=threshold-1 then --if the number of used levels is equal to
the full size of the queue
full_sig<='1'; --full signal becomes high
else full_sig<='0';
end if;
end if;
end process;
full <= full_sig; --the signal will light up an LED to tell the user
that the queue is full
end behavior;
ii. testbench
library IEEE;
use IEEE.std_logic_1164.all;
entity Queue_tb is
end Queue_tb;
architecture testbench of Queue_tb is
component Queue IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
Write_en : in STD_LOGIC;
read_en : in STD_LOGIC;
done_translating : in STD_LOGIC;
Data_in : in STD_LOGIC_VECTOR(7 downto 0);
full: out std_logic;
Data_out: out STD_LOGIC_VECTOR(7 downto 0));
end component;
signal clk : STD_LOGIC; --10 MHz clock
signal Write_en : STD_LOGIC := '0';
signal Read_en : STD_LOGIC := '0';
signal done_translating: STD_LOGIC := '0';
signal full : std_logic :='0';
signal Data_in : STD_LOGIC_Vector(7 downto 0) :=
"00000000";
signal Data_out: STD_LOGIC_Vector(7 downto 0) := "00000000";
62
64. begin
uut : Queue PORT MAP(
clk => CLK,
Read_en => Read_en,
Write_en => Write_en,
Data_in => Data_in,
full => full,
done_translating=>done_translating,
Data_out => Data_out);
clk_proc : process
BEGIN
CLK <= '0';
wait for 5ns;
CLK <= '1';
wait for 5ns;
END PROCESS clk_proc;
stim_proc : process
begin
write_en<= '0';
read_en<= '0';
wait for 8 ns;
write_en<='1';
wait for 30 ns;
Data_in <= "00000000";
wait for 5 ns;
Data_in <= "00000001";
wait for 5 ns;
Data_in <= "00000010";
wait for 5 ns;
Data_in <= "00000100";
wait for 5 ns;
Data_in<= "00001000";
wait for 5 ns;
Data_in <= "00010000";
63
65. wait for 10 ns;
write_en<='0';
wait for 5 ns;
read_en<='1';
done_translating<='1';
wait for 15 ns;
write_en<='1';
wait for 8 ns;
Data_in <= "10000000";
wait for 5 ns;
Data_in <= "11000000";
wait for 5 ns;
Data_in <= "11100000";
wait for 5 ns;
Data_in <= "11110000";
wait for 5 ns;
Data_in<= "11111000";
wait for 5 ns;
Data_in<= "11111100";
wait for 5 ns;
Data_in<= "11111110";
wait for 5 ns;
done_translating<='1';
wait for 8 ns;
Data_in<= "11111110";
wait for 8 ns;
Data_in<= "11111111";
wait for 8 ns;
wait;
end process stim_proc;
end testbench;
5. Morse Translator
i. code
64
66. library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY translator IS
PORT ( clk : in STD_LOGIC; --10MHz master clock
Data_out_buffer: in STD_LOGIC_VECTOR(7 downto 0);
--from buffer
done : out STD_LOGIC;
Morse_code: out STD_LOGIC_VECTOR(9 downto 0));
end translator;
architecture behaviour of translator is
BEGIN
process(Data_out_buffer)
begin
done<= '0';
case Data_out_buffer is
when "01000001" => Morse_code <= "0111000000"; --A
done<='1';
when "01000010" => Morse_code <= "1101010100"; --B
done<='1';
when "01000011" => Morse_code <= "1101110100"; --C
done<='1';
when "01000100" => Morse_code <= "1101010000"; --D
done<='1';
when "01000101" => Morse_code <= "0100000000"; --E
done<='1';
when "01000110" => Morse_code <= "0101110100"; --F
done<='1';
when "01000111" => Morse_code <= "1111010000"; --G
done<='1';
when "01001000" => Morse_code <= "0101010100"; --H
done<='1';
when "01001001" => Morse_code <= "0101000000"; --I
done<='1';
when "01001010" => Morse_code <= "0111111100"; --J
done<='1';
when "01001011" => Morse_code <= "1101110000"; --K
done<='1';
when "01001100" => Morse_code <= "0111010100"; --L
done<='1';
when "01001101" => Morse_code <= "1111000000"; --M
done<='1';
when "01001110" => Morse_code <= "1101000000"; --N
done<='1';
when "01001111" => Morse_code <= "1111110000"; --O
done<='1';
when "01010000" => Morse_code <= "0111110100"; --P
done<='1';
65
67. when "01010001" => Morse_code <= "1111011100"; --Q
done<='1';
when "01010010" => Morse_code <= "0111010000"; --R
done<='1';
when "01010011" => Morse_code <= "0101010000"; --S
done<='1';
when "01010100" => Morse_code <= "1100000000"; --T
done<='1';
when "01010101" => Morse_code <= "0101110000"; --U
done<='1';
when "01010110" => Morse_code <= "0101011100"; --V
done<='1';
when "01010111" => Morse_code <= "0111110000"; --W
done<='1';
when "01011000" => Morse_code <= "1101011100"; --X
done<='1';
when "01011001" => Morse_code <= "1101111100"; --Y
done<='1';
when "01011010" => Morse_code <= "1111010100"; --Z
done<='1';
when "00000000" => Morse_code <= "1111111111"; --0
done<='1';
when "00000001" => Morse_code <= "0111111111"; --1
done<='1';
when "00000010" => Morse_code <= "0101111111"; --2
done<='1';
when "00000011" => Morse_code <= "0101011111"; --3
done<='1';
when "00000100" => Morse_code <= "0101010111"; --4
done<='1';
when "00000101" => Morse_code <= "0101010101"; --5
done<='1';
when "00000110" => Morse_code <= "1101010101"; --6
done<='1';
when "00000111" => Morse_code <= "1111010101"; --7
done<='1';
when "00001000" => Morse_code <= "1111110101"; --8
done<='1';
when "00001001" => Morse_code <= "1111111101"; --9
done<='1';
when "00100000" => Morse_code <= "0000000000"; --space
done<='1';
when "01100001" => Morse_code <= "0111000000"; --a
done<='1';
when "01100010" => Morse_code <= "1101010100"; --b
done<='1';
when "01100011" => Morse_code <= "1101110100"; --c
done<='1';
when "01100100" => Morse_code <= "1101010000"; --d
done<='1';
when "01100101" => Morse_code <= "0100000000"; --e
66
68. done<='1';
when "01100110" => Morse_code <= "0101110100"; --f
done<='1';
when "01100111" => Morse_code <= "1111010000"; --g
done<='1';
when "01101000" => Morse_code <= "0101010100"; --h
done<='1';
when "01101001" => Morse_code <= "0101000000"; --i
done<='1';
when "01101010" => Morse_code <= "0111111100"; --j
done<='1';
when "01101011" => Morse_code <= "1101110000"; --k
done<='1';
when "01101100" => Morse_code <= "0111010100"; --l
done<='1';
when "01101101" => Morse_code <= "1111000000"; --m
done<='1';
when "01101110" => Morse_code <= "1101000000"; --n
done<='1';
when "01101111" => Morse_code <= "1111110000"; --o
done<='1';
when "01110000" => Morse_code <= "0111110100"; --p
done<='1';
when "01110001" => Morse_code <= "1111011100"; --q
done<='1';
when "01110010" => Morse_code <= "0111010000"; --r
done<='1';
when "01110011" => Morse_code <= "0101010000"; --s
done<='1';
when "01110100" => Morse_code <= "1100000000"; --t
done<='1';
when "01110101" => Morse_code <= "0101110000"; --u
done<='1';
when "01110110" => Morse_code <= "0101011100"; --v
done<='1';
when "01110111" => Morse_code <= "0111110000"; --w
done<='1';
when "01111000" => Morse_code <= "1101011100"; --x
done<='1';
when "01111001" => Morse_code <= "1101111100"; --y
done<='1';
when "01111010" => Morse_code <= "1111010100"; --z
done<='1';
when others => Morse_code <= "1111111111"; --in case of an
invalid input, the output will be a zero
done<='1';
end case;
end process;
end behaviour;
67
69. ii. testbench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity translator_tb is
end translator_tb ;
architecture testbench of translator_tb is
component translator is
PORT ( clk : in STD_LOGIC; --2MHz master clock
Data_out_buffer: in STD_LOGIC_VECTOR(7 downto 0);
--from buffer
done : out STD_LOGIC;
Morse_code: out STD_LOGIC_VECTOR(9 downto 0));
end component;
signal clk: std_logic;
signal Data_out_buffer: std_logic_vector(7 downto 0) :="00000000";
signal done: std_logic :='0';
signal Morse_code: std_logic_vector(9 downto 0) :="0000000000";
begin
uut : translator PORT MAP(
clk => clk,
data_out_buffer => data_out_buffer,
Morse_code => Morse_code,
done =>done);
clk_proc : process
BEGIN
CLK <= '0';
wait for 5ns;
CLK <= '1';
wait for 5ns;
end process clk_proc;
stim_proc : process
begin
Data_out_buffer<="01001000";
wait for 20 ns;
Data_out_buffer<="01100101";
wait for 20 ns;
Data_out_buffer<="01101100";
wait for 20 ns;
68
70. Data_out_buffer<="01101100";
wait for 20 ns;
Data_out_buffer<="01001111";
wait for 20 ns;
Data_out_buffer<="10101010"; --random number
wait for 20 ns;
wait;
end process stim_proc;
end testbench;
6. Morse Interpreter
a. Controller
i. code
-- Code your design here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY morse_interpreter_controller IS
PORT ( clk : in STD_LOGIC; -- 10 MHz clk
translation_done : in STD_LOGIC; -- indicates new character is ready
space: in STD_LOGIC; -- from datapath
not_space: in STD_LOGIC; -- from datapath
dot: in STD_LOGIC; -- from datapath
dash: in STD_LOGIC; -- from datapath
end_char: in STD_LOGIC; -- from datapath
load_en : out STD_LOGIC; -- send to datapath
shift_en : out STD_LOGIC; -- send to datapath
check_bits_en: out STD_LOGIC; -- send to datapath
count_T_en: out STD_LOGIC; -- send to datapath
count_3T_en: out STD_LOGIC; -- send to datapath
count_7T_en: out STD_LOGIC; -- send to datapath
end_trans : out STD_LOGIC);-- indicates the translation is
over
end morse_interpreter_controller;
architecture behavior of morse_interpreter_controller is
--Signals
type state_type is (idle, shift_register, shift_bits, check_bits, clear,
time_3T, time_T, time_7T, time_within_letter, time_between_letters); --
states of FSM
69
71. signal current_state, next_state : state_type := idle;
signal count_7T, count_3T, count_T, count_within_char, count_between_letters:
integer:=0; -- count the time between works and characters
signal count_between_letters_TC, count_T_TC, count_3T_TC, count_7T_TC,
count_within_char_TC: std_logic:='0';
signal count_3T_en_signal, count_T_en_signal, count_7T_en_signal,
count_within_char_en, count_between_letters_en : std_logic:='0';
BEGIN
-- update state machine states
stateUpdate: process(clk)
BEGIN
if rising_edge(clk) then
current_state <= next_state;
end if;
end process stateUpdate;
-- CONTROLLER
controller: process (current_state, translation_done, space, not_space, dot,
dash, end_char, count_3T_TC, count_T_TC,
count_7T_TC,count_T,count_within_char_TC, count_between_letters_TC)
begin
-- defaults; will only change inside the states
count_T_en_signal<='0';
count_3T_en_signal<='0';
count_7T_en_signal<='0';
count_within_char_en<='0';
count_between_letters_en<='0';
load_en<='0';
shift_en<='0';
check_bits_en<='0';
count_3T_en<='0';
count_7T_en<='0';
count_T_en<='0';
end_trans<='0';
case (current_state) is
when idle=>
if translation_done='1' then -- ready to receive new bits
next_state<=shift_register;
end if;
when shift_register=>
load_en<='1'; -- enables to load data into a register
if space='1' then -- if the character is a space
next_state<=time_7T; -- waits for 7T
elsif not_space='1' then
next_state<=check_bits; --waits for 3T
end if;
70
72. when time_between_letters=>
count_between_letters_en<='1';
if count_between_letters_TC = '1' then -- after waited 3T
next_state<= clear;
end if;
when shift_bits=>
shift_en<='1'; -- enables to left shift the bits
next_state<= check_bits;
when check_bits=>
check_bits_en<='1';
if dot='1' then
next_state<= time_T; -- dot
elsif dash='1' then
next_state<= time_3T; -- dash
end if;
if end_char='1' then
next_state<= time_between_letters; -- end of chacracter
end if;
when time_within_letter=> -- time between dots and dashes
count_within_char_en<='1';
if count_within_char_TC = '1' then -- after waited T (1000000)
next_state<= shift_bits;
end if;
when time_3T=>
count_3T_en<='1';
count_3T_en_signal<='1';
if count_3T_TC = '1' then -- after waited 3T (3000000)
next_state<= time_within_letter;
end if;
when time_T=>
count_T_en<='1';
count_T_en_signal<='1';
if count_T_TC = '1' then -- after waited T (1000000)
next_state<= time_within_letter;
end if;
when time_7T=>
count_7T_en<='1';
count_7T_en_signal<='1';
if count_7T_TC = '1' then -- after waited 7T (7000000)
next_state<= clear;
end if;
when clear=>
71
73. end_trans<='1';
next_state<=idle;
when others=> -- deals with other cases
next_state<=idle;
end case;
end process;
-- WAITING TIME FOR MORSE CODE
time_within_char: process(clk, count_within_char_en)
begin
if rising_edge(clk) then
if count_within_char_en = '1' then
count_within_char<= count_within_char+1;
if count_within_char= 999999 then
count_within_char_TC<='1';
else
count_within_char_TC<='0';
end if;
else
count_within_char <= 0; -- zero the counter
end if;
end if;
end process;
time_Between_two_letters: process(clk, count_between_letters_en)
begin
if rising_edge(clk) then
if count_between_letters_en = '1' then
count_between_letters<= count_between_letters+1;
if count_between_letters= 999999 then
count_between_letters_TC<='1';
else
count_between_letters_TC<='0';
end if;
else
count_between_letters <= 0; -- zero the counter
end if;
end if;
end process;
wait_time_T: process (clk, count_T_en_signal)
begin
if rising_edge(clk) then
if count_T_en_signal='1' then -- in time_T state
count_T<=count_T+1;
if count_T = 999999 then
count_T_TC <= '1';
else
72
74. count_T_TC<='0';
end if;
end if;
if count_T_en_signal ='0' then -- zero the counter
count_T<=0;
end if;
end if;
end process;
wait_time_3T: process (clk, count_3T_en_signal)
begin
if rising_edge(clk) then
if count_3T_en_signal='1' then -- in time_3T state
count_3T<=count_3T+1;
if count_3T = 2999999 then
count_3T_TC <= '1';
else
count_3T_TC<='0';
end if;
end if;
if count_3T_en_signal ='0' then -- zero the counter
count_3T<=0;
end if;
end if;
end process;
wait_time_7T: process (clk, count_7T_en_signal)
begin
if rising_edge(clk) then
if count_7T_en_signal='1' then -- in time_7T state
count_7T<=count_7T+1;
if count_7T = 5999999 then
count_7T_TC <= '1';
else
count_7T_TC<='0';
end if;
end if;
if count_7T_en_signal='0' then -- zero the counter
count_7T<=0;
end if;
end if;
end process;
end behavior;
ii. testbench
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
73
75. entity morse_interpreter_controller_tb is
end morse_interpreter_controller_tb;
architecture testbench of morse_interpreter_controller_tb is
component morse_interpreter_controller
PORT ( clk : in STD_LOGIC; -- 10 MHz clk
translation_done : in STD_LOGIC; -- indicates new character is ready
space: in STD_LOGIC; -- from datapath
not_space: in STD_LOGIC; -- from datapath
dot: in STD_LOGIC; -- from datapath
dash: in STD_LOGIC; -- from datapath
end_char: in STD_LOGIC; -- from datapath
load_en : out STD_LOGIC; -- send to datapath
shift_en : out STD_LOGIC; -- send to datapath
check_bits_en: out STD_LOGIC; -- send to datapath
count_T_en: out STD_LOGIC; -- send to datapath
count_3T_en: out STD_LOGIC; -- send to datapath
count_7T_en: out STD_LOGIC; -- send to datapath
end_trans : out STD_LOGIC);-- indicates the translation is
over
-- signals
end component;
signal clk, dot, dash, end_char, translation_done, space, not_space, load_en,
shift_en, check_bits_en, end_trans,count_T_en,count_3T_en,count_7T_en:
std_logic := '0';
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut : morse_interpreter_controller PORT MAP(
clk => clk,
translation_done=> translation_done,
space=> space,
not_space=>not_space,
dot=> dot,
dash=> dash,
end_char=>end_char,
load_en=>load_en,
shift_en=>shift_en,
check_bits_en=>check_bits_en,
count_T_en=> count_T_en,
count_3T_en=>count_3T_en,
count_7T_en=> count_7T_en,
end_trans=>end_trans);
74
76. clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
-- testing for space case
wait for 5*clk_period;
translation_done<= '1'; -- ready to receive new character
wait for 1*clk_period;
translation_done<= '0';
wait for 1*clk_period;
space<='1';
wait for 70*clk_period;
space<='0';
wait for 70*clk_period;
-- testing for other characters
wait for 5*clk_period;
translation_done<= '1'; -- ready to receive new character
wait for 1*clk_period;
translation_done<= '0';
wait for 1*clk_period;
not_space<='1';
wait for 30*clk_period;
not_space<='0';
dot<='1';
wait for 10*clk_period;
dot<='0';
wait for 10*clk_period;
dash<='1';
wait for 30*clk_period;
dash<='0';
wait for 10*clk_period;
end_char<='1';
wait for 50*clk_period;
end_char<='0';
wait for 1*clk_period;
end process;
end testbench;
b. Datapath
i. Code
-- Code your design here
library IEEE;
75
77. use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
ENTITY morse_interpreter_datapath IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
translation_done: in std_logic; -- coming from translator;
indicates a new character was converted to morse code
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit
signal encoding morse signal
count_T_en : in STD_LOGIC; -- from controller
count_3T_en : in STD_LOGIC; -- from controller
count_7T_en : in STD_LOGIC; -- from controller
load_en : in STD_LOGIC; -- from controller
shift_en : in STD_LOGIC; -- from controller
check_bits_en : in STD_LOGIC; -- from controller
space : out STD_LOGIC; -- send to controlller
no_space : out STD_LOGIC; -- send to controlller
dot : out STD_LOGIC; -- send to controlller
dash : out STD_LOGIC; -- send to controlller
end_char : out STD_LOGIC; -- send to controlller
sound : out STD_LOGIC;
light : out STD_LOGIC);
end morse_interpreter_datapath;
architecture behavior of morse_interpreter_datapath is
-- signal
signal reg: std_logic_vector(9 downto 0):= (others=>'0');-- holds 10 bits of
data
signal fill_reg: std_logic_vector(1 downto 0):= "00"; -- used to left shift
bits out of the register
BEGIN
-- DATAPATH
translation: process (clk, translation_done, load_en, morse_in, shift_en,
check_bits_en)
begin
if rising_edge(clk) then
--if translation_done = '1' then -- gets new morse code
if load_en='1' then -- enables morse code to be saved in the
register
reg<= morse_in; -- register gets the morse code value
if morse_in = "0000000000" then -- if the character is a space
space<='1'; -- flags we received a space
no_space<='0';
else
no_space<='1'; -- flags we have a regular character
space<='0';
end if;
76
78. else
space<='0';
no_space<='0';
reg<=reg; -- register gets its current value
end if;
if shift_en='1' then
reg<= reg(7 downto 0)&fill_reg; -- left shifting the bits out
of the register
end if;
if check_bits_en='1' then
if reg(9 downto 8)="01" then
dot<='1'; -- flags we have a dot
dash<='0';
end_char<='0';
elsif reg(9 downto 8)="11" then
dash<='1'; -- flags we have a dash
dot<='0';
end_char<='0';
elsif reg(9 downto 8)="00" then
end_char<='1'; -- flags we reached end othe character
dash<='0';
dot<='0';
end if;
else
dot<='0';
dash<='0';
end_char<='0';
end if;
if count_T_en='1' then -- during the time for morse code
sound <='1';
light <='1';
elsif count_3T_en='1' then -- during the time for morse code
sound <='1';
light <='1';
elsif count_7T_en ='1' then -- during the time for morse code
sound <='1';
light <='1';
else
sound <='0';
light <='0';
end if;
--end if;
end if;
end process;
77
79. end behavior;
ii. testbench
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity morse_interpreter_datapath_tb is
end morse_interpreter_datapath_tb;
architecture testbench of morse_interpreter_datapath_tb is
component morse_interpreter_datapath
PORT ( clk : in STD_LOGIC; --10 MHz clock
translation_done: in std_logic; -- coming from translator;
indicates a new character was converted to morse code
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit
signal encoding morse signal
count_T_en : in STD_LOGIC; -- from controller
count_3T_en : in STD_LOGIC; -- from controller
count_7T_en : in STD_LOGIC; -- from controller
load_en : in STD_LOGIC; -- from controller
shift_en : in STD_LOGIC; -- from controller
check_bits_en : in STD_LOGIC; -- from controller
space : out STD_LOGIC; -- send to controlller
no_space : out STD_LOGIC; -- send to controlller
dot : out STD_LOGIC; -- send to controlller
dash : out STD_LOGIC; -- send to controlller
end_char : out STD_LOGIC; -- send to controlller
sound : out STD_LOGIC;
light : out STD_LOGIC);
end component;
-- signals
signal clk, check_bits_en, load_en, shift_en, translation_done, count_T_en,
count_3T_en, count_7T_en, space, no_space, dot, dash, end_char, sound, light
: std_logic := '0';
signal morse_in : std_logic_vector(9 downto 0):= "0000000000";
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut : morse_interpreter_datapath PORT MAP(
clk => clk,
translation_done=>translation_done,
78
81. count_T_en<='0';
wait for 1*clk_period;
count_3T_en<='1';
wait for 2*clk_period;
count_3T_en<='0';
wait for 1*clk_period;
count_7T_en<='1';
wait for 2*clk_period;
count_7T_en<='0';
wait for 1*clk_period;
translation_done<='0';
wait for 1*clk_period;
morse_in<="0000000000"; -- space character
load_en<='1'; -- passes morse code into register
wait for 1*clk_period;
load_en<='0';
wait for 1*clk_period;
end process;
end testbench;
c. Shell
i. code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity morse_interpreter_top is
Port ( clk : in STD_LOGIC; -- 10 MHz clk
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit signal encoding
morse signal
translation_done : in STD_LOGIC; -- indicates new character is ready
end_trans: out STD_LOGIC; -- indicates that finished translating one
character
sound: out STD_LOGIC;
light: out STD_LOGIC);
end morse_interpreter_top;
architecture Behavioral of morse_interpreter_top is
80
82. component morse_interpreter_controller IS
PORT ( clk : in STD_LOGIC; -- 10 MHz clk
translation_done : in STD_LOGIC; -- indicates new character is ready
space: in STD_LOGIC; -- from datapath
not_space: in STD_LOGIC; -- from datapath
dot: in STD_LOGIC; -- from datapath
dash: in STD_LOGIC; -- from datapath
end_char: in STD_LOGIC; -- from datapath
load_en : out STD_LOGIC; -- send to datapath
shift_en : out STD_LOGIC; -- send to datapath
check_bits_en: out STD_LOGIC; -- send to datapath
count_T_en: out STD_LOGIC; -- send to datapath
count_3T_en: out STD_LOGIC; -- send to datapath
count_7T_en: out STD_LOGIC; -- send to datapath
end_trans : out STD_LOGIC);-- indicates the translation is
over
end component;
component morse_interpreter_datapath IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
translation_done: in std_logic; -- coming from translator;
indicates a new character was converted to morse code
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit
signal encoding morse signal
count_T_en : in STD_LOGIC; -- from controller
count_3T_en : in STD_LOGIC; -- from controller
count_7T_en : in STD_LOGIC; -- from controller
load_en : in STD_LOGIC; -- from controller
shift_en : in STD_LOGIC; -- from controller
check_bits_en : in STD_LOGIC; -- from controller
space : out STD_LOGIC; -- send to controlller
no_space : out STD_LOGIC; -- send to controlller
dot : out STD_LOGIC; -- send to controlller
dash : out STD_LOGIC; -- send to controlller
end_char : out STD_LOGIC; -- send to controlller
sound : out STD_LOGIC;
light : out STD_LOGIC);
end component;
signal space,not_space,dot, dash, end_char, load_en, shift_en, check_bits_en,
count_T_en, count_3T_en, count_7T_en, no_space: STD_LOGIC :='0';
begin
uut_inter : morse_interpreter_controller
port map (clk => clk,
translation_done=> translation_done,
space=> space,
not_space=>not_space,
dot=> dot,
81
83. dash=> dash,
end_char=>end_char,
load_en=>load_en,
shift_en=>shift_en,
check_bits_en=>check_bits_en,
count_T_en=> count_T_en,
count_3T_en=>count_3T_en,
count_7T_en=> count_7T_en,
end_trans=>end_trans);
uut2_inter: morse_interpreter_datapath
PORT MAP( clk => clk,
translation_done => translation_done,
morse_in=> morse_in,
count_T_en=>count_T_en,
count_3T_en=>count_3T_en,
count_7T_en=>count_7T_en,
space=>space,
load_en=>load_en,
check_bits_en=> check_bits_en,
shift_en=>shift_en,
no_space=>not_space,
dot=>dot,
dash=>dash,
end_char=>end_char,
sound=>sound,
light=>light);
end Behavioral;
ii. testbench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity morse_interpreter_top_tb is
end morse_interpreter_top_tb;
architecture Testbench of morse_interpreter_top_tb is
component morse_interpreter_top is
Port ( clk : in STD_LOGIC; -- 10 MHz clk
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit signal encoding
morse signal
translation_done : in STD_LOGIC; -- indicates new character is ready
82
84. end_trans: out STD_LOGIC; -- indicates that finished translating one
character
sound: out STD_LOGIC;
light: out STD_LOGIC);
end component;
signal clk : std_logic := '0';
signal translation_done : std_logic:= '0';
signal morse_in: std_logic_vector(9 downto 0):= (others => '0');
signal end_trans, sound, light :std_logic :='0';
constant clk_period : time := 100ns; -- 10 MHz clock
begin
uut0_inter_top: morse_interpreter_top
port map ( clk => clk,
morse_in=> morse_in,
translation_done=> translation_done,
end_trans => end_trans,
sound=> sound,
light => light);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
begin
wait for 5*clk_period;
morse_in<="0111000000";
translation_done <='1';
wait for 1*clk_period;
translation_done <='0';
wait for 15000000*clk_period;
morse_in<="0000000000";
translation_done <='1';
wait for 1*clk_period;
translation_done <='0';
wait for 8000000*clk_period;
wait for 1042*clk_period;
end process;
end Testbench;
83
85. 7. Square Wave Oscillator
a. Code:
-- Code your design here
library IEEE;
use IEEE.std_logic_1164.all;
ENTITY square_wave_oscillator IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
sound_wave : out STD_LOGIC);-- square wave at 500Hz
end square_wave_oscillator;
architecture behavior of square_wave_oscillator is
signal counter, counter_high : integer:=0;
signal rate : integer:=999; -- for squarewave at 500Hz (10^6/500)
signal twice_rate : integer:=4000;
signal initial_sound : std_logic:='0';
begin
square_wave: process (clk)
begin
if rising_edge(clk) then
counter<= counter+1;
if (counter=rate) then
initial_sound<= NOT(initial_sound);
counter<=0; -- zeros the counter
end if;
end if;
end process;
sound_wave<=initial_sound;
end behavior;
b. Testbench:
-- Code your testbench here
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity square_wave_oscillator_tb is
end square_wave_oscillator_tb;
architecture testbench of square_wave_oscillator_tb is
84
86. component square_wave_oscillator
PORT ( clk : in STD_LOGIC; --10 MHz clock
sound_wave : out STD_LOGIC);-- square wave at 500Hz
end component;
signal clk, sound_wave: std_logic := '0';
constant clk_period: time := 100ns; -- 10MHz clock
begin
uut_square : square_wave_oscillator PORT MAP(
clk => clk,
sound_wave=>sound_wave);
clkgen_proc: process
begin
clk <= not(clk);
wait for clk_period/2;
end process clkgen_proc;
stimulus_proc: process
begin
wait for 1000* clk_period;
end process;
end testbench;
8. Final MUX
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity final_mux is
Port ( sound_wave: in std_logic; --from sound oscillator
sound: in std_logic; --from interpreter
sound_final: out STD_LOGIC);
end final_mux;
architecture Behavioral of final_mux is
begin
wave: process (sound,sound_wave)
begin
if sound ='1' then
if sound_wave='1' then
sound_final<='1';
else
85
87. sound_final<='0';
end if;
end if;
end process;
end Behavioral;
9. Final Top Code (Shell File)
i. code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity final_top is
port (clk : in STD_LOGIC;
data_in : in STD_LOGIC; -- 1bit signal from AD2;
sound_final: out STD_LOGIC;
end_tick : out STD_LOGIC;
Full: out STD_LOGIC;
transmitter_data_out : out STD_LOGIC;-- 1 bit signal to AD2
light: out STD_LOGIC);
end final_top;
architecture Behavioral of final_top is
component SCI_Receiver_top is
Port ( clk : in STD_LOGIC;
data_in : in STD_LOGIC; -- 1bit signal from AD2;
done_tick: out STD_LOGIC;
data_out : out STD_LOGIC_VECTOR(7 downto 0));-- 8 bits
of parallel data
end component;
component SCI_Transmitter_top is
Port ( clk : in STD_LOGIC;
receiver_data : in STD_LOGIC_VECTOR(7 DOWNTO 0);
done_tick: in std_logic;
transmitter_data_out : out STD_LOGIC;-- 1 bit signal
to AD2
end_tick : out STD_LOGIC);-- indicates finished passing
the data to AD2
end component;
component morse_interpreter_top is
Port ( clk : in STD_LOGIC; -- 10 MHz clk
morse_in : in STD_LOGIC_VECTOR(9 downto 0); -- 10 bit signal
encoding morse signal
86
88. translation_done : in STD_LOGIC; -- indicates new character is
ready
end_trans: out STD_LOGIC; -- indicates that finished
translating one character
sound: out STD_LOGIC;
light: out STD_LOGIC);
end component;
component Queue IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
Write_en : in STD_LOGIC; --input character
read_en : in STD_LOGIC; --enter pressed
done_translating: in std_logic;
Data_in_Q : in STD_LOGIC_VECTOR(7 downto 0);
Data_out_Q: out STD_LOGIC_VECTOR(7 downto 0);
full: out std_logic);
end component;
component check_character IS
PORT ( clk : in STD_LOGIC; --2MHz master clock
Data_in_receiver : in STD_LOGIC_VECTOR(7 downto
0); --from sci receiver
read_en : out std_logic);
end component;
component square_wave_oscillator IS
PORT ( clk : in STD_LOGIC; --10 MHz clock
sound_wave : out STD_LOGIC);-- square wave at 500Hz
end component;
component translator IS
PORT ( clk : in STD_LOGIC; --10MHz master clock
Data_out_buffer: in STD_LOGIC_VECTOR(7 downto 0);
--from buffer
done : out STD_LOGIC;
Morse_code: out STD_LOGIC_VECTOR(9 downto 0));
end component;
component final_mux is
Port ( sound_wave: in std_logic; --from sound oscillator
sound: in std_logic; --from interpreter
sound_final: out STD_LOGIC);
end component;
signal
done,sound_wave,full,read_en,done_translating,write_en,done_tick,transl
ation_done,end_trans,sound : STD_LOGIC; -- 1bit signal from AD2;
signal data_out_buffer,data_out,
receiver_data,data_in_Q,data_out_Q,data_in_receiver :
STD_LOGIC_VECTOR(7 downto 0);
87
89. signal morse_in,morse_code : STD_LOGIC_VECTOR(9 downto 0); -- 10 bit
signal encoding morse signal
begin
uutf1 : SCI_Receiver_top
port map(clk =>clk,
data_in => data_in,
done_tick=>done_tick,
data_out =>data_out);-- 8 bits of parallel data
uutf2: SCI_Transmitter_top
Port map ( clk =>clk,
receiver_data =>data_out,
done_tick=>done_tick,
transmitter_data_out =>transmitter_data_out,-- 1 bit signal to
AD2
end_tick => end_tick);-- indicates finished passing the data
to AD2
uutf3: check_character
Port map ( clk =>clk, --2MHz master clock
Data_in_receiver=> data_out, --from sci receiver
read_en => read_en);
uutf4: Queue
Port map ( clk => clk, --10 MHz clock
Write_en=> done_tick, --input character
read_en =>read_en, --enter pressed
done_translating =>end_trans,
Data_in_Q=>data_out,
Data_out_Q=>data_out_Q,
full=>full);
uutf5: translator
Port map( clk =>clk, --10MHz master clock
Data_out_buffer=>data_out_Q, --from buffer
done =>done,
Morse_code => Morse_code);
uutf6: morse_interpreter_top
Port map ( clk => clk, -- 10 MHz clk
morse_in =>Morse_code, -- 10 bit signal encoding morse signal
translation_done =>done, -- indicates new character is ready
end_trans=> end_trans,-- indicates that finished translating
one character
sound=>sound,
light=>light);
uutf7: square_wave_oscillator
PORT map ( clk => clk, --10 MHz clock
sound_wave =>sound_wave);-- square wave at 500Hz
88
90. uutf8: final_mux
port map (sound_wave =>sound_wave, --from sound oscillator
sound=>sound, --from interpreter
sound_final=>sound_final);
end Behavioral;
ii. testbench
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity final_top_tb is
end final_top_tb;
architecture testbench of final_top_tb is
component final_top is
port (clk : in STD_LOGIC;
data_in : in STD_LOGIC; -- 1bit signal from AD2;
sound_final: out STD_LOGIC;
end_tick : out STD_LOGIC;
Full: out STD_LOGIC;
transmitter_data_out : out STD_LOGIC;-- 1 bit signal to AD2
light: out STD_LOGIC);
end component;
signal clk, data_in,sound_final,end_tick,transmitter_data_out,light :
std_logic := '0';
constant clk_period : time := 100ns; -- 10 MHz clock
-- Data definitions
BEGIN
uuttb: final_top
port map ( clk => clk,
data_in=> data_in, -- 1bit signal from AD2;
sound_final =>sound_final,
end_tick =>end_tick,
transmitter_data_out=>transmitter_data_out,-- 1 bit signal to AD2
light=>light);
-- Clock process definitions
clk_process :process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
stim_proc: process
89
91. begin
data_in<='1';
wait for 10420*clk_period;
data_in<='0';
wait for 10420*clk_period;
data_in<='1';
wait for 10420*clk_period;
data_in<='0';
wait for 10420*clk_period;
data_in<='1';
wait for 10420*clk_period;
data_in<='1';
wait for 10420*clk_period;
data_in<='1';
wait for 10420*clk_period;
data_in<='0';
wait for 10420*clk_period;
data_in<='0';
wait for 10420*clk_period;
data_in<='1';
wait for 10420*clk_period;
wait for 400*clk_period;
wait;
end process;
end Testbench;
90