Lab 4: TinyRV1 Processor
Part E: FPGA Prototype V2
Lab 4 will give you experience designing, implementing, testing, and prototyping a single-cycle processor microarchitecture and a specialized accelerator. The processor will implement the TinyRV1 instruction set. The instruction set manual is located here:
The lab will continue to leverage concepts from Topic 2: Combinational Logic, Topic 3: Boolean Algebra, Topic 4: Combinational Building Blocks, Topic 6: Sequential Logic, Topic 7: Finite-State Machines, and Topic 8: Sequential Building Blocks. The lab will also leverage concepts from Topic 9: Instruction Set Architecture and Topic 10: Single-Cycle Processors The lab will continue to provide opportunities to leverage the three key abstraction principles: modularity, hierarchy, and regularity.
The lab includes seven parts:
-
Part A: Processor Components
- Due 11/6 @ 11:59pm via GitHub
- Students should work on Part A before, during, and after your assigned lab section during the week of 11/3
- Pre-lab survey on Canvas is (roughly) due by end of lab section during the week of 11/3
-
Part B: TinyRV1 Processor
- Due 11/13 @ 11:59pm via GitHub
- Students should work on Part B before, during, and after your assigned lab section during the week of 11/10
-
Part C: Accumulate Accelerator
- Due 11/25 @ 11:59pm via GitHub
- Students should plan to submit Part C before they leave for Thanksgiving Break
-
Part D: FPGA Prototype v1
- Due week of 11/17 during assigned lab section
- This part will focus on prototyping the code developed in Part A+B
- Even though completed with a partner, every student must turn in their own paper check-off sheet in their lab section!
-
Part E: FPGA Prototype v2
- Due week of 12/1 during assigned lab section
- This part will focus on prototyping the code developed in Part A+B+C
- Even though completed with a partner, every student must turn in their own paper check-off sheet in their lab section!
-
Part F: TinyRV1 Assembly
- Due 12/4 @ 11:59pm via GitHub
- This part will include all of the assembly developed during Part D+E
-
Part G: Report
- Due on 12/8 at 11:59pm for all groups!
- Post-lab survey on Canvas is due at the same time as the report
This handout assumes that you have read and understand the course tutorials and that you have attended the discussion sections. This handout assumes you have successfully completed Parts A, B, and C, meaning your processor, memory bus, SPI, and accumulate assembly program are all working in simulation.
What do we do if Parts A, B, and C are not done?
If Parts A and B are not done then you cannot get started on Part E. Based on our experiences in the very first lab section we have decided to skip prototyping the accumulate accelerator so we can focus on the processor in this lab, so if your accelerator is not working please continue to work on fixing it and have your revision submitted by this Thursday night.
Here are the steps to get started:
- Step 1. Find your lab partner
- Step 2. Find a free workstation
- Step 3. Ask the TAs for a lab check-off sheet (each student needs their own check-off sheet)
For each lab report task you must take some notes, save a screenshot, and/or record some data for your lab report. The lab report is not due until the last day of classes.
For each lab check-off task you must raise your hand and have a TA come to check-off your work. The TA will ask you the questions included as part of the lab check-off task and the assess your understanding using the following rubric: mastery; accomplished; emerging; beginning. If the TA and students together feel the students have not mastered the lab check-off task, the students are encouraged to take a few minutes and try again.
The Final Lab
This is the final lab of the semester. It will require students to leverage all they have learned throughout the semester. Students will need to:
- use iverilog to simulate various designs on
ecelinux; - use Quartus to integrate, analyze, synthesize, and configure an FPGA prototype;
- write, assemble, and load assembly programs for their TinyRV1 processor;
- wire various electrical components on a breadboard; and
- use the oscilloscope to visualize electrical signals.
If students have not mastered these skills, they might need to revisit material from previous lab assignments. Students must maintain a sense of urgency and leverage all of they learned in order to complete the lab assignment. There are no extensions and students cannot complete Part E at any other time except during their assigned lab section.
Lab Check-Off Task 1: Setup Lab Kit
The TAs will pass out an ECE 2300 Lab Kit to each group. The TAs will record the kit number on your check-off sheet. For this lab, you will receive the FPGA board, a USB-B cable, a USB-C cable, and a component box with some jumper wires, a piezo buzzer, a digital distance sensor, and a USB flash drive. Use the USB-B cable to plug the FPGA board into the workstation.
1. Simulate the Single-Cycle TinyRV1 Processor
Before starting to work on an FPGA prototype, you must make sure you have
a working Verilog hardware design that has been thoroughly tested in
simulation. We will be rerunning the same test simulations and using the
same interactive simulators as last week to ensure our accumulate
assembly program is fully functional. One student should start VS Code on
the workstation, log into the ecelinux servers, source the setup
script, and make sure their group repository is up to date.
Where XX is your group number.
1.1. Verify All Four Labs
Now run all of the tests from a clean build to ensure your design is fully functional.
Lab Check-Off Task 2: Verify All Four Labs
Show a TA that your hardware designs are passing all of your tests. You must pass all of the tests from Lab 1, Lab 2, and Lab 3. You must also pass all of the Lab 4 Part A and B tests. You can still receive full credit if you are failing some of the tests from Part C as long as you explain your plan for fixing the accelerator by the Thursday deadline.
1.2. Verify Accumulate Assembly Program
We now want to run your accumulate program on the ISA simulator and the single-cycle processor simulator. Start by assembling your accumulate assembly program into a machine program.
Recall from Part C that the interactive simulator for the accumulate accelerator is using the following array loaded into the memory.
addr data size result result seven
(hex) (dec) (Dec) (dec) (hex) segment
---------------------------------------
000 36 1 36 0x024 4
004 26 2 62 0x03e 30
008 69 3 131 0x083 3
00c 57 4 188 0x0bc 28
010 11 5 199 0x0c7 7
014 68 6 267 0x10b 11
018 41 7 308 0x134 20
01c 90 8 398 0x18e 14
020 32 9 430 0x1ae 14
024 76 10 506 0x1fa 26
028 44 11 550 0x226 6
02c 19 12 569 0x239 25
030 17 13 586 0x24a 10
034 59 14 645 0x285 5
038 99 15 744 0x2e8 8
03c 49 16 793 0x319 25
040 65 17 858 0x35a 26
044 12 18 870 0x366 6
048 55 19 925 0x39d 29
04c 0 20 925 0x39d 29
050 51 21 976 0x3d0 16
054 42 22 1018 0x3fa 26
058 82 23 1100 0x44c 12
05c 23 24 1123 0x463 3
060 21 25 1144 0x478 24
064 54 26 1198 0x4ae 14
068 83 27 1281 0x501 1
06c 31 28 1312 0x520 0
070 16 29 1328 0x530 16
074 76 30 1404 0x57c 28
078 21 31 1425 0x591 17
07c 4 32 1429 0x595 21
The above table shows the address, data, and the expected result when accumulating every possible size up to 32 elements. Now build the ISA simulator and run the accumulate machine program on the ISA simulator using the text user interface (TUI).
Remember once you start the simulation you can use the following commands
to emulate entering the size on the switches (i.e., input in0) and
pressing the button (i.e., setting input in2 to one for a few cycles,
then setting input in2 back to zero).
Since in0 is 4 we find the row in the table when the size is 4. The
final sum should be 188 which is 0x0bc in hex. Verify in the TUI that the
final result is indeed 0x0bc.
The ISA simulator will display the total number of cycles in the lower right corner. Recall that our accumulate assembly program looks like this:
# set breadboard pin high for timing
addi x3, x0, 1
sw x3, 0x21c(x0)
#''' LAB ASSIGNMENT ''''''''''''''''''''''''''''''''''''''''''''''''''''
# Write your accumulate loop
#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
# Be sure to understand the code above and below so you know what
# register stores the size and what register stores the result.
# set breadboard pin low for timing
sw x0, 0x21c(x0)
Recall that memory address 0x21c is the memory-mapped IO address for
out3. So our assembly program includes instructions to set out3 to
one before the accumulate loop and set out3 to zero after the
accumulate loop. The ISA simulator monitors the number of cycles that
out3 is one; we call these "stat" cycles (for performance statistics).
The ISA simulator also reports the number of "stat" cycles in the lower
right hand corner. Make sure the number of stat cycles makes sense given
the number of instructions in each iteration of your accumulate loop and
the number of iterations executed by the loop.
Now build the single-cycle processor simulator and run the accumulate machine program on this simulator using the text user interface (TUI).
% cd ${HOME}/ece2300/groupXX/build
% make proc-scycle-sim
% ./proc-scycle-sim +bin=accumulate.bin +tui
Just like on the ISA simulator, emulate entering a size of 4 on the switches and pressing the button. Verify that the final result is indeed 0x0bc.
Lab Check-Off Task 3: Verify Accumulate Assembly Program
Show a TA your accumulate assembly program correctly executing on the ISA simulator with a size of 31. Clearly explain to the TA why the number of stat cycles makes sense given your specific accumulate loop. Then show the TA your accumulate assembly program correctly executing on the single-cycle processor simulator.
1.4. Copying Files to Workstation
We now need to get the files for your design from ecelinux onto the
workstation. This requires multiple steps.
-
Step 1. Click Microsoft Edge on the desktop to open a web-browser on the workstation to log into GitHub and then find your repository
-
Step 2. Start PowerShell by clicking the Start menu then searching for Windows PowerShell
-
Step 3. Use the following command to change to your home directory on the workstation in the lab (where
netidis your Cornell NetID)
- Step 4. Clone your repo onto the workstation by using this command in
PowerShell (where
netidis your Cornell NetID, notice we are using https!):
-
Step 5. In the Connect to GitHub pop-up, click Sign in with your browser
-
Step 6. You may be asked for your GitHub username again and you may be asked to authorize the Git Credential Manager; click authorize git-ecosystem
-
Step 7. Verify that you have successfully cloned your repo by changing into your repo and using
treeon the workstation:
2. Setup Quartus Project
Click Quartus (Quartus Prime 18.1) on the desktop to start Quartus. Important: Ensure that the Quartus Version is 18.1 and not 23.1. Then, click Run the Quartus Prime software. You might need to try starting Quartus twice. Setup a new Quartus project using the New Project Wizard:
- Directory, Name, Top-Level Entity
- You must enter the working directory as follows with your NetID!
- Working directory:
C:\Users\netid\lab4e - Name of this project:
lab4d - Name of top-level design entity:
lab4e - Click Next
- Directory does not exist. Do you want to create it?
- Click yes
- Project Type
- Choose Empty Project
- Click Next
- Add Files
- Click User Libraries...
- Click triple dots to the right of Project library name
- Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX where XX is your group number
- Click Select Folder
- Click Add
- Click OK
- Click triple dots to right of File name
- Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX > lab4 where XX is your group number
- Shift-click on every Verilog hardware design file (do not include
any files in the
testorsimsubdirectories) - Click Open
- Click Next
- Family, Device, and Board Settings
- Click Board tab
- Family: Cyclone V
- Select DE0-CV Development Board
- Make sure Create top-level design file is checked
- Click Next
- EDA Tool Settings
- Click Next
- Summary
- Click Finish
As in previous labs, you must use the following steps to ensure Quartus knows your design includes RTL modeling:
- Choose Assignments > Settings from the menu
- Select the category Compiler Settings > Verilog HDL Input
- Under Verilog version click SystemVerilog
- Click OK
3. TinyRV1 Processor FPGA Prototype
We will now integrate your TinyRV1 single-cycle processor into a complete embedded system, synthesize the design, and configure the FPGA so we can run machine programs on the real prototype. We will use the TinyRV1 processor FPGA prototype to measure the delay of your accumulate assembly program and to implement a door monitoring embedded system.
3.1. Integrate
We want to implement a TinyRV1 processor FPGA prototype with the following specification:
- Input to clock divider is connected to the 50MHz clock on the FPGA board
rst(ACTIVE LOW!) is connected to the reset button on the board using a synchronizer- The left most push button will be the go button (see below)
- The left five switches are
in0 - The right five switches are
in1 - The right three push buttons are the three least significant bits of
in2(ACTIVE LOW!) - The two seven-segment displays on the left are
out0 - The two seven-segment displays in the middle are
out1 - The two seven-segment displays on the right are
out2 - The left most LED shows the go bit
- The right eight LEDs are for
out3 - The general-purpose pins will be used to connect to the SPI
- SCLK connects to GPIO_1[1] which connects to D0 on USB-to-SPI adapter
- MOSI connects to GPIO_1[3] which connects to D1 on USB-to-SPI adapter
- MISO connects to GPIO_1[5] which connects to D2 on USB-to-SPI adapter
- CS connects to GPIO_1[7] which connects to D3 on USB-to-SPI adapter
- The general-purpose pins will also be used with the oscilloscope and
two new external I/O devices
- The least significant bit of
out3connects to GPIO_1[11] which will be probed by the oscilloscope - The distance sensor connects to GPIO_1[13]
- The output of the multi-note player connects to GPIO_1[15]
- The least significant bit of
Here is a block diagram and annotated FPGA board and breadboard diagram illustrating the system we will be prototyping for Part E.


The differences between this system and what you implemented in the previous lab are highlighted in red on the block diagram and include two new external I/O devices.
Distance Sensor
We will be using a digital distance sensor in our door monitoring embedded system. The digital distance sensor looks like this:

The sensor uses light detection and ranging (LIDAR) to measure distance by emitting laser pulses and measuring the time it takes for them to bounce back. You can read more about the sensor here:
The sensor has three pins:
- Ground marked with a negative (-) sign
- Vdd marked with a plus (+) sign
- Output marked as out
You will need to connect the Vdd and ground pins appropriately on the breadboard, and connect the output to the correct general-purpose I/O pin. Make sure to point the LIDAR towards the edge of the breadboard and that no wires obstruct the LIDAR.
The sensor is preconfigured to detect objects within 100cm. This makes it a digital distance sensor meaning the output with be either one or zero based on whether or not the sensor detects an object. The sensor is ACTIVE LOW so the output is one when there is no object detected within 100cm and the output is zero when there is an object detected within 100cm.
Multi-Note Player
We will be integrating your multi-note player from Lab 3 as an external
output device for our door monitoring embedded system. The note output
from the multi-note player will be connected to a piezo buzzer using a
general-purpose I/O pin just as in Lab 3. The play_note_rdy signal is
connected back to the play_note_val through a DFFR. This means the
multi-note player will continuously play whatever note is specified using
play_note_num. The play_note_num input is connected to out3, so to
play a note from an assembly program we can simply store the desired note
to the appropriate memory-mapped I/O address. For example, the following
assembly fragment plays the note 3:
Here is a template you can use for your top-level design.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | |
You will need to also include the following modules.
`include "lab1/DisplayOpt_GL.v"
`include "lab3/DFFRE_RTL.v"
`include "lab3/DFFR_RTL.v"
`include "lab3/ClockDiv_RTL.v"
`include "lab3/MultiNotePlayer_RTL.v"
`include "lab4/Synchronizer_RTL.v"
`include "lab4/ProcScycle.v"
`include "lab4/MemoryBus_RTL.v"
`include "lab4/SPI_RTL.v"
`include "lab4/Memory.v"
Use the following steps when you are ready to integrate the counter.
- Double-click on DE0_CV_golden_top
- Instantiate the template shown above
- Fill in the connections to the top-level ports
- Be sure to include all the required modules at the top
- Choose File > Save from the menu
Then make sure to hook up the SPI interface on the breadboard as mentioned above.
- SCLK connects to GPIO_1[1] which connects to D0 on USB-to-SPI adapter
- MOSI connects to GPIO_1[3] which connects to D1 on USB-to-SPI adapter
- MISO connects to GPIO_1[5] which connects to D2 on USB-to-SPI adapter
- CS connects to GPIO_1[7] which connects to D3 on USB-to-SPI adapter
Connect the oscilloscope probe to GPIO_1[11]. Make sure your distance sensor is connected to GPIO_1[13] and the piezo buzzer is connected to GPIO_1[15]. There is a red LED on the back of the distance sensor which will go on and off when it detects an obstacle; test it out to make sure it is working.
Lab Check-Off Task 4: Discuss TinyRV1 Processor Integration
Show a TA your breadboard wiring and your top-level integration. Discuss how the connections provided in the template implement the specification. Confirm with the TA that you have correctly accounted for the fact that reset, all push-buttons, and the distance sensor are active low! Show how you have connected GPIO_1[11] to the oscilloscope. Make sure the red LED on the back of the distance sensor goes on and off when it detects an obstacle. Take your time and double check all connections! Synthesizing the processor takes 10 minutes so get your connections right the first time!
3.2. Synthesize
You will need to use the following timing constraint file:
set_max_delay -from [all_inputs] -to [all_outputs] 20
set_min_delay -from [all_inputs] -to [all_outputs] 0
create_clock -name CLOCK_50 -period 20 [get_ports {CLOCK_50}]
create_generated_clock -name clk -divide_by 4 -source CLOCK_50 \
[get_nets {clock_div|counter_reg|q[1]}]
create_generated_clock -name mnp_clk -divide_by 1024 -source CLOCK_50 \
[get_nets {mnp_clock_div|counter_reg|q[9]}]
set_output_delay -add_delay -clock clk -max 0 [all_outputs]
set_output_delay -add_delay -clock clk -min 0 [all_outputs]
set_input_delay -add_delay -clock clk -max 0 [all_inputs]
set_input_delay -add_delay -clock clk -min 0 [all_inputs]
We are now using two different clock dividers, one for the processor and one for the multi-note player, so we must specify two different generated clocks.
Now use the following steps to synthesize your design.
- Choose Processing > Start Compilation from the menu
- Wait ten minutes for synthesis to complete
- While you are waiting go ahead and start reading the next section and you can even start working on your door monitoring assembly program!
How do I fix "can't open Verilog Design File" errors?
This probably means you did not setup the user library correctly, so
Quartus cannot find the files you are including using the include
Verilog preprocessor directive. You can use the following steps to
fix this:
- Choose Assignments > Settings from the menu
- Select the category Libraries
- Click triple dots to the right of Project library name
- Click on This PC, then navigate to your cloned repo by choosing Windows (C:) > Users > netid > groupXX where XX is your group number
- Click Select Folder
- Click Add
- Click OK
- Choose Processing > Start Compilation from the menu to see if this fixes the issue
How do I fix "Verilog HDL syntax" errors?
This might be because you did not configure Quartus to use SystemVerilog! You can use the following steps to ensure Quartus knows your design includes RTL modeling:
- Choose Assignments > Settings from the menu
- Select the category Compiler Settings > Verilog HDL Input
- Under Verilog version click SystemVerilog
- Click OK
Once your design is fully synthesized, let's use the RTL viewer to appreciate how far we have come this semester.
- RTL Viewer
- Choose Tools > Netlist Viewer > RTL Viewer from the menu
- Use the Netlist Navigator to gradually drill down in the hierarchy
as follows:
- ProcScycle
- ProcScycleDpath
- ALU_32b
- Adder_32b_GL
- AdderCarrySelect_16b_GL
- AdderRippleCarry_8b_GL
- FullAdder_GL
- Take a screenshot of the entire RTL viewer window; it must clearly show the Netlist Navigator with the full hierarchy from the top to the full adder on the left and the gate-level implementation of the full adder on the right.
- Choose File > Close from menu to close the RTL viewer
Lab Report Task 1: Collect Data for Single-Cycle Processor
Save the screenshot of the entire RTL viewer window for your lab report.
3.3. Configure
Now we are finally ready to configure the FPGA for TinyRV1 single-cycle processor prototype.
- Choose Tools > Programmer from the menu
- Click Hardware Setup
- Currently selected hardware: USB-Blaster [USB-0]
- Click Close
- Click Start
Start by testing out the default assembly program as in the last lab.
Then use PowerShell on the workstation to assemble the assembly test
programs and load them into the physical memory in our FPGA prototype
over SPI. These commands should be done on the workstation not on
ecelinux!
% cd C:\Users\netid\groupXX
% mkdir build
% cd build
% python ..\scripts\tinyrv1-assemble -o test1.bin ..\lab4\asm\test1.asm
% python ..\scripts\tinyrv1-load test1.bin
Remember to first reset the processor, then load the program, then press
the go button. Then try assembling and loading both test1.asm and
test2.asm and confirm the perform as expected. Then take a look at
test3.asm.
This test program simply reads the push buttons and outputs the result to
out3 which is connected to the oscilloscope, LEDs, and the multi-note
player. Try pressing the right most push button and confirm that you can
hear a note and that you can see a signal on the oscilloscope.
Lab Check-Off Task 5: Demonstrate TinyRV1 Processor Prototype
Show a TA your processor running test3.asm. Show pressing the right
most push button and demonstrate you can hear a note and can see a
signal on the oscilloscope.
4. TinyRV1 Accumulate Assembly Program
We will now perform an experiment to measure the delay of the accumulate assembly program you wrote in Part C. Reset your processor and load the accumulate assembly program.
% cd C:\Users\netid\groupXX
% mkdir build
% cd build
% python ..\scripts\tinyrv1-assemble -o accumulate.bin ..\lab4\asm\accumulate.asm
% python ..\scripts\tinyrv1-load accumulate.bin
Then set the size switches to be 4 and press the go button. Recall that the expected final result is 0x0bc. Since the seven-segment display only shows values from 0-31, it will only be able to show the bottom five bits of the complete result. We can look in the "seven segment" column in the table included above to see what the seven-segment display should show in the real FPGA prototype. For size 4, the seven-segment display should show 28. Verify that this is indeed what we see using the FPGA prototype. Try some other sizes.
You already calculated the number of cycles it will take your processor to execute the assembly program to accumulate 31 elements. Given the clock period of the processor, what do you expect the delay of your processor running the accumulate assembly program with a size of 31 to be in nanoseconds?
Go ahead and try a size of 31 on your FPGA prototype and confirm the
output is 17. Recall that our assembly program includes instructions to
set out3 to one before the accumulate loop and set out3 to zero after
the accumulate loop. The least significant bit of out3 is connected to
GPIO_1[11] so we can probe this on the oscilloscope to get an accurate
measurement of the delay of our accumulate loop. Go ahead and run this
experiment. Use the cursors on the oscilloscope to measure how long out3
is one in nanoseconds and capture a screenshot of the oscilloscope. Does
this match your expectation?
Lab Report Task 2: Save Screenshot for Accumulate Assembly Program
Save the screenshot from the oscilloscope that clearly shows the total time of your accumulate assembly program when accumulating 31 elements.
Lab Check-Off Task 6: Demonstrate the Accumulate Assembly Program
The TA will ask you to try a size and confirm that your FPGA prototype is producing the correct result. Then show a TA your processor FPGA prototype correctly accumulating 31 elements. Show the TA the screen capture of your oscilloscope data including the cursors showing the delay of your accumulate assembly loop when accumulating 31 elements. Clearly explain to the TA why the delay measured using the oscilloscope makes sense. Hint: Consider both the number of instructions per iteration, the number of iterations, and then time per cycle.
5. Door Monitoring Embedded System
The final culminating design is to implement both the software and hardware for a door monitoring embedded system which leverages all you have learned throughout the semester. The hardware is based on the TinyRV1 embedded system you implemented on the FPGA in the previous parts which includes the two new external I/O devices: a distance sensor and a multi-note player. It should be no surprise by now that we will be taking an incremental approach.
- Step 1: Implement and test distance sensor
- Step 2: Implement and test sensor and counter
- Step 3: Implement and test sensor, counter, and alarm
- Step 4: Implement and test sensor, counter, and beep
For each step, we recommend first writing out some pseudo-code. Then you
can either develop the assembly program on ecelinux and use the ISA and
single-cycle processor simulator first to verify its correctness or just
go ahead and try developing the program directly on the FPGA prototype.
If you are more confident in your mastery of both the software and
hardware in your embedded system feel free to try directly developing on
the FPGA prototype, or consider using the simulator for just some of the
steps.
5.1. Step 1: Distance Sensor
Implement an assembly program in door-monitor-step1.asm that reads the
distance sensor and outputs the result on the seven-segment displays
using out0. If the system does not detect an object, then it should
display a zero. If the system does detect an object it should display a
one.
5.2. Step 2: Sensor and Counter
Implement an assembly program in door-monitor-step2.asm that adds a
traffic counter to the door monitor embedded system. If the system
detects a person walking by it should increment the traffic counter by
one. The traffic counter should be displayed on the seven-segment
displays using out0.
Note that you cannot simply increment the counter whenever the distance sensor is one. Whenever a person walks by, the distance sensor will output one for many, many cycles. You need to instead wait for the distance sensor to be one, then wait for the distance sensor to go back to zero, and then increment the counter.
5.3. Step 3: Sensor, Counter, and Alarm
Implement an assembly program in door-monitor-step3.asm that adds an
alarm to the door monitoring embedded system.
If the system detects a person walking by it should increment the traffic
counter by one. The traffic counter should be displayed on the
seven-segment displays using out0.
In addition, the system should play a note using the multi-note player whenever a person walks by. You can play the note when the sensor first goes high, or when the sensor goes low. For this step, the system should just start playing a note when it detects the first person and then never stop playing the note. You can reset the system to turn off the alarm.
5.4. Step 4: Sensor, Counter, and Beep
Implement an assembly program in door-monitor-step4.asm that turns the
alarm into a beep for the door monitoring embedded system.
If the system detects a person walking by it should increment the traffic
counter by one. The traffic counter should be displayed on the
seven-segment displays using out0.
In addition, the system should play a beep using the multi-note player whenever a person walks by. You can play the beep when the sensor first goes high, or when the sensor goes low. To play a beep, first play a note using the multi-note player, then add a delay, then play note zero to turn off the multi-note player. To add a delay simply create a loop that does nothing except iterates for maybe 500ms. With a clock period of 40ns, waiting 500ms might require several million iterations. You can initialize a register with a large immediate value (which will then serve as the loop counter) by loading the large number from memory like this:
When you are finished with this step your door monitoring embedded system should sense whenever anyone walks by, increment the traffic counter, and make a small beep.
Take a minute to appreciate all you have accomplished! You have now created all of the hardware and software for a complete (albeit simple) embedded system including:
- GL implementation of a five-digit numeric display
- GL implementation of a 32-bit ALU including an adder and equality comparator
- RTL implementation of a multi-note player including various structural datapaths and a FSM-based control unit
- GL and RTL implementation of a TinyRV1 single-cycle processor
- RTL implementation of a memory bus and SPI
- Integrating all of this into the hardware for a door monitoring embedded system with many different memory-mapped external I/O devices
- Bread boarding the SPI adapter, distance sensor, and piezo buzzer
- Developing a software door monitor program with 30+ assembly instructions
This has required implementing over 50 hardware modules using over 5000 lines of both gate-level and register-transfer level Verilog modeling. Even more importantly, you have verified these modules with hundreds of test cases. You have also manually implemented eight software programs with a total of almost 100 assembly instructions. You should be very proud of this tremendous accomplishment!
Lab Check-Off Task 7: Demonstrate the Door Monitoring Embedded System
Show a TA your door monitoring embedded system in action! You do not need to show the door monitoring system in simulation; just show the TA everything working on the real prototype.
Lab Check-Off Task 8: Turn in Lab Kit
When you are finished with your demo, pack up your ECE 2300 Lab Kit. Put the jumper wires, a piezo buzzer, a digital distance center, and a USB flash drive back in the component box. Return the FPGA board, USB cables, and component box to a TA who will then record the kit number on your check-off sheet, initial the final check-off, and then collect your check-off sheet.
6. Optional Extension: Advanced Door Monitoring Embedded System
This section is an optional extension to the main lab and is meant for students who have already completed all of the above tasks. Students might consider adding one of several more advanced features to their door monitoring embedded system:
-
Play a few notes instead of just beeping every time a person passes by.
-
Use the switches to set a "room capacity limit" which should be displayed on the seven-segment displays; when the room reaches capacity an alarm should go off indicating that the room is now full.
-
Use a switch to configure the door monitoring embedded system into one of two modes: in "day mode" should function exactly as above; in "night mode" instead of counting traffic, the system should sound an alarm if someone passes by
-
Use switches to enable a secret alarm passcode to turn off the alarm in night mode.
-
Use a second distance sensor to see if you can detect which way a person is passing; increment the counter when a person walks one way and decrement the counter when a person walks the opposite way