Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
Lab Manual for ECE 424 and ECE 426 Interactive Teaching Aid
Created by:
Lance Haney, Computer Engineering Major Micah Nance, Computer Engineering Major
Nathan Young, Computer Engineering Major
ii
Table of Contents 1 Introduction............................................................................................................................................1 2 Connecting the UP3 Development Board to the Computer ...................................................................2 3 Tutorial 1: Basic Introduction to the Quartus II IDE .............................................................................6 4 Connecting the “GO LED” External Hardware ...................................................................................14
4.1 Component Design.........................................................................................................................14 4.1.1 LED Circuit Analysis..................................................................................................................14 4.1.2 Pushbutton Circuit Analysis........................................................................................................16 4.1.3 Interface Design ..........................................................................................................................16 4.2 Board Assembly .............................................................................................................................17
5 Tutorial 2: “GO LED” Implemented Using VHDL.............................................................................20 5.1 LMN Technologies Pseudo-Random Delay for “GO LED” VHDL Design .................................30
6 Tutorial 3: “GO LED” Implemented Using NIOS II Processor ..........................................................31 6.1 Quartus II – Part 1 ..........................................................................................................................31 6.2 SOPC Builder.................................................................................................................................31 6.3 Quartus II – Part 2 ..........................................................................................................................35 6.4 NIOS II IDE ...................................................................................................................................37
Appendix A: LMN Technologies “GO LED” VHDL Code........................................................................43 Appendix B: LMN Technologies “GO LED” C Code.................................................................................49
1
1 Introduction Welcome to the Interactive Teaching Aid User Manual written by LMN Technologies. This manual will teach you how to program the UP3 Development Board using the Quartus II IDE, Nios II IDE, and SOPC Builder software packages. The software versions that we used at the time of the creation of this lab manual were Quartus II version 4.2 and NIOS II Evaluation Kit 1.1, which contains the NIOS II IDE. The FPGA that the UP3 Development Board utilizes at the time of this document’s creation is the Cyclone EP1C6Q240C8. We have designed Tutorial 1 to make the user familiar with the Quartus II IDE and introduce basic concepts that later tutorials will build upon, allowing students to create advanced designs. No prior knowledge of the Quartus II IDE is necessary and the tutorial uses basic concepts taught in most microcomputer fundamentals courses in order to provide a simple design to focus more on the familiarization of the software package. We have designed Tutorial 2 to allow the user to reproduce the “GO LED” Reaction Timer in VHDL that LMN Technologies originally implemented for Dr. Collins. This game requires the use of concepts typically covered in a digital design course that utilizes the VHDL programming language. The user of Tutorial 2 should have a basic familiarity with Quartus II IDE. We have designed Tutorial 3 to allow the user to reproduce the “GO LED” Reaction Timer utilizing the NIOS II soft-core processor and the C programming language that LMN Technologies originally implemented for Dr. Collins. This game requires the use of concepts typically covered in an embedded systems course that utilizes the C programming language. The user of Tutorial 3 should have a basic familiarity with the Quartus II and NIOS II IDEs along with the C programming language.
2
2 Connecting the UP3 Development Board to the Computer This section will show you how to connect the UP3 Development Board, shown in Figure 2.1, to a desktop computer.
Figure 2.1
1) Begin with the USB ByteBlaster II cable and a USB Software Guard, shown in Figure 2.2. If a network license is enabling your software, you will not need the USB Guard.
Figure 2.2
3
2) Hook the ByteBlaster II cable to the parallel port of your computer and insert the USB Software Guard into an open USB port as shown in Figure 2.3.
Figure 2.3
Figure 2.4 shows the JP11 and JP12 connectors on the UP3. JP12 is for a JTAG communication cable.
Figure 2.4
4
3) Connect the other end of the ByteBlaster II cable to the JTAG port on the UP3 as shown in Figure 2.5.
Figure 2.5
4) Now connect the AC adaptor to the board as shown in Figure 2.6. The blue button you see in the
figure is the power switch.
Figure 2.6
5
Figure 2.7 circles the J3 expansion Header. You will be using this in the next step.
Figure 2.7
5) Connect a standard IDE hard drive cable to the J3 expansion header as shown in Figure 2.8. You
will use this cable to interface the UP3 with a breadboard.
Figure 2.8
6
3 Tutorial 1: Basic Introduction to the Quartus II IDE This tutorial will demonstrate the process of programming the UP3 Development Board using Quartus II and a simple schematic.
1) Connect the UP3 Development Board to your computer (see section titled ‘Connecting the UP3 Board’ for more information).
2) Open the Quartus II software. You can use Start->Programs->Altera->Quartus 4.2 to access the program.
3) Click ‘File->New Project Wizard’. 4) Click Next. When you see the dialog box shown in Figure 3.1, enter
“C:/altera/qdesigns42/tutorial1/” as the working directory, and “tutorial1” for the name of the project and for the name of the top-level entry of the project.
Figure 3.1
5) Click ‘Next’. 6) Click ‘Next’. You should now see the dialog shown in Figure 3.2.
7
Figure 3.2
7) Select ‘Cyclone’ as the targeted device family. 8) Set the ‘Speed grade’ to “8”. 9) Select the ‘EP1C6Q240C8’ device and click ‘Next’. 10) If the boxes on the following dialog are checked, uncheck them as shown in Figure 3.3.
8
Figure 3.3
11) Click ‘Next’ 12) Click ‘Finish’ 13) Click File->New. A window will appear (see Figure 3.4). Select ‘Block Diagram/Schematic File’
and click OK.
9
Figure 3.4
14) Once you have opened a schematic, click on the ‘Symbol Tool’ in the left pane, which is labeled in Figure 3.5. Alternatively, you can double-click inside the schematic to bring up the ‘Symbol Tool.’
Figure 3.5
15) Figure 3.6 shows the ‘Symbol Wizard’ window. Type “input” into the ‘Name:’ box in order to select an input pin component.
10
Figure 3.6
16) Place two input pins onto the schematic. Right click on a pin and select ‘Properties’ from the drop-down menu as shown in Figure 3.7. Now, rename it as “clock”. Rename the other input “push_button_1”.
Figure 3.7
11
17) Use the ‘Symbol Tool’ to create and place an output buffer. Name it “led0”. 18) Use the ‘Symbol Tool’ to create and place an inverter (‘not’) and a D Flip-Flop (‘dff’) onto your
schematic. 19) Arrange the components on your schematic as shown in Figure 3.8.
Figure 3.8
20) Select the ‘Selection and Smart Drawing Tool’ or the ‘Orthogonal Node Tool’ shown in Figure 3.9. Then, draw wires between your components to attach them as shown in Figure 3.10.
Figure 3.9
Figure 3.10
21) Hold down the CTRL key and left-click on your input buffers and your output buffer to select all
three of these components at once. Then, right-click on one of the components and select ‘Locate->Locate in Assignment Editor’ as shown in Figure 3.11.
12
Figure 3.11
22) Figure 3.12 shows the ‘Assignment Editor’. Click on the ‘Pin’ button in the top right portion of
the editor. Then, double click where the ‘clock’ row meets the ‘Location’ column. Type in or select “PIN_29” for your ‘clock’ input, “PIN_62” for your ‘push_button_1’ input, and “PIN_56” for your ‘led0’ output. PIN_29 is an internal 48 MHz clock on the UP3 Development Board. Figure 3.13 shows the on-board pushbuttons on the right and the small on-board LEDs in the lower left.
Figure 3.12
13
Figure 3.13
23) Close the ‘Assignment Editor’ and save the assignments. 24) Click on the ‘Processing’ menu and select ‘Start Compilation.’ 25) The compilation should complete with zero errors and one warning. 26) Click on the ‘Tools’ menu and select ‘Programmer’ 27) Next to the ‘Hardware Setup’ button, you will see either “No Hardware” or a device name. If you
see a device name, skip this step. Otherwise, in the ‘Programmer’, click ‘Hardware Setup’. Then click ‘Add Hardware.’ The dialog shown in Figure 3.14 will appear. Inside this dialog, select ‘ByteBlasterMV or ByteBlaster II’ as your hardware type and ‘LPT1’ as your port. Click ‘OK.’ Click ‘Close.’
Figure 3.14
14
28) Make sure you are in JTAG mode and click the ‘Program/Configure’ box shown in Figure 3.15. Click ‘Start.’
Figure 3.15
29) Once the Progress bar reaches 100%, you have successfully programmed your UP3 board. 30) Press and hold the push button labeled SW7 on the UP3 to watch your LED light up.
4 Connecting the “GO LED” External Hardware This portion of the tutorial will guide the user through the steps to construct all external hardware necessary for this project’s use of the UP3 development board. All needed materials can be found in Figure 4.1.
Component QuantityBreadboard 1LED's (1.8V@10mA) 8Resistors (10k) 2Resistors (150) 8Pushbuttons 2IDE cable (40 pin) 1Wire strippers 1Jumper wire pack 1
Figure 4.1
4.1 Component Design This section will begin with an overview of each component of the external hardware.
4.1.1 LED Circuit Analysis To ensure an appropriate current through the LED’s, a current limiting resistor is required. The output pins of the UP3 will supply Vcc (5V) to the breadboard for the LED circuit shown in Figure 4.2. Using Ohm’s Law and Kirchoff's voltage law, the value of the resistor is determined by:
IV
R R= or I
VVR fcc −=
The LEDs we will use have specifications of Vf (the forward voltage of the diode) and I to be 1.8V and 20mA, respectively. Given those values, calculations yield a resistor value of about 150 ohms.
15
Figure 4.2
16
4.1.2 Pushbutton Circuit Analysis A single-pole single-throw (SPST) pushbutton momentary switch will be the sole input for each player to play the game. The switches are external to the board as to not damage the more sensitive portions of the design. Figure 4.3 shows a circuit, which implements such pushbutton input scheme. When the user closes the pushbutton, the voltage is pulled low and the board will receive logic 0. With the pushbutton open, the voltage will be pulled high and the board will receive logic 1.
10k
To board
+5V
Figure 4.3
4.1.3 Interface Design In order to connect the breadboard and all its components to the UP3, you will use a standard 40 pin IDE cable. Figure 4.4 shows the pin assignments for a standard 40 pin IDE cable.
Figure 4.4
After plugging the IDE cable into the J3 expansion header (see Figure 4.5), the pin assignments will correspond as shown in Figure 4.6. NOTE: The red wire on the IDE cable should be farthest from the corner of the board.
17
Figure 4.5
Function IDE cable pin J3 Header pin UP3 pin assignment Ground 2 2 Gnd Vcc 3 3 217 LED1 (p1 score=3) 4 4 221 LED2 (p1 score=2) 5 5 206 LED3 (p1 score=1) 6 6 218 LED4 (tie game) 7 7 215 LED5 (p2 score=1) 8 8 219 LED6 (p2 score=2) 9 9 216 LED7 (p2 score=3) 10 10 220 LED8 (Go LED) 11 11 207 P1 Button 12 12 222 P2 Button 13 13 208
Figure 4.6
4.2 Board Assembly The following steps will guide you through assembling the external hardware associated with the “GO LED” exercise. IMPORTANT: To reduce clutter and confusion; build each of the components in order from the right side of the board to the left.
1) Acquire all parts listed in Figure 4.6. 2) Construct seven LED circuits (Figure 4.7) on the breadboard to display the score. Be sure to plan
for the Vcc wire coming from the UP3 by leaving an open socket near the top of each column for each of the LED’s. Connect the ground portion of the LED circuit to the bottom row of the breadboard.
3) Construct one more LED circuit for the “go LED” in the same fashion as Step 2. Separate this LED to designate it from the score keeping LED’s.
18
Figure 4.7
4) Using the pushbuttons, 10k resistors, and jumper wires, construct two pushbutton circuits (Figure 4.8). Connect each of the Vcc portions of each circuit to one of the long strips along the top edge of the breadboard. Also, connect the ground portion of the circuit to one of the long strips along the bottom edge of the breadboard.
Figure 4.8
5) Referencing Figure 4.9, connect the bare ends of the IDE cable to each of the corresponding components on the breadboard. You may need to strip each wire in order to form a complete connection to the board. The numbering for the wires begins with one as the red wire and proceeds numerically along adjacent wires. The ordering of the pins, wires, and components is very important, and error could lead to board misbehavior. Also, recognize the placement of the pushbutton wires (wire 12 and 13) between the 10k pull-up resistor and pushbutton lead. NOTE: pin 2 (Gnd) and 3 (Vcc) should be connected to the two strips along the top of the breadboard.
19
Then, using a jumper, connect the Gnd row to the bottom row of the breadboard and ground all circuits. Use two more jumpers to connect the Vcc row to each of the pushbutton circuits.
Figure 4.9
The unit is ready to be connected to the UP3 development board. In order for the pin assignments to be preserved, it is very important that the connector be oriented so that the red wire of the IDE cable is farthest from the outside corner.
20
5 Tutorial 2: “GO LED” Implemented Using VHDL This tutorial will demonstrate the process of programming the UP3 Development Board using Quartus II and the “GO LED” interactive program utilizing external hardware.
1) Make sure the UP3 Development Board is connected properly to your computer (see section titled Connecting the UP3 Board for more information).
2) Make sure the “GO LED” externa1 hardware is properly connected and that the ribbon cable connecting the external hardware to the UP3 development is properly installed (see section titled Connecting the “GO LED” External Hardware).
3) Open the Quartus II software. You can use Start->Programs->Altera->Quartus x.x to access the program.
4) Click File->New Project. This opens the New Project Wizard. 5) Click Next. When you see the dialog box enter “C:/altera/qdesigns41/tutorial2/” as the working
directory, and “tutorial2” for the name of the project and for the name of the top-level entry of the project. Click Next. If the directory does not exist, select to create it.
6) There will be no files to add to the project so on the Add Files Dialog Box click Next. 7) Select the ‘Cyclone’ FPGA and create a new ‘Block Diagram/Schematic File’ as detailed in
Tutorial 1. 8) Create the block for the VHDL controller of the system by using the Block Tool on the left toolbar
as shown in Figure 5.1.
Figure 5.1
9) Once you draw the block in the schematic area, right click the box and select Block Properties as shown in Figure 5.2.
21
Figure 5.2
10) Under Block Properties, select the General tab and enter the name of the block to be goLed_controller (Figure 5.3).
Figure 5.3
11) Under Block Properties, select the I/O tab and enter the name of the signals and their type. Click 'Add' for each signal. This design contains 12 signals (6 inputs/6 outputs). Enter the signals as shown in Figure 5.4.
22
Figure 5.4
12) Click OK and Quartus II will automatically update the block with the appropriate signals (Figure 5.5).
Figure 5.5
23
13) Now the input pads for clock, reset, p1input, p2input, and start game should be inserted as described in Tutorial 1 and using the Orthogonal Conduit Tool (Figure 5.6) connect the input pads to the goLed_controller (Figure 5.7).
Figure 5.6
Figure 5.7
14) Using the Orthogonal Node Tool (Figure 5.8), draw a signal line that connects to the goLed_controller (Figure 5.9). Name this signal line end_delay by right clicking the line once it is connected and selecting properties.
Figure 5.8
Figure 5.9
15) Using the Orthogonal Bus Tool (Figure 5.10), connect two bus lines to the goLed_controller (Figure 5.11). Name the bus lines p1score[1..0] and p2score[1..0] respectively.
Figure 5.10
Figure 5.11
24
16) Using the Orthogonal Node Tool connect two signal lines to each bus and name two of the new signal lines p1score[0] and p1score[1] and the other two signal lines p2score[0] and p2score[1] as shown in Figure 5.12.
Figure 5.12
17) To obtain the appropriate scores, the p1score and p2score vectors must have there individual signals sent through a digital logic setup shown in Figure 5.13. You can find the parts for this setup by right clicking an empty space in the schematic and selecting Insert Symbol. This setup allows the two bit vectors to produce three distinct scores for each player
AND2
inst3
AND2
inst4
AND2
inst5
NOT
inst6
NOT
inst7
AND2
inst8
AND2
inst9
AND2
inst10
NOT
inst11
NOT
inst12
play er1_3
play er1_1
play er1_2
p1score[0]
p1score[0]
p1score[0]
p1score[1]
p1score[1]
p1score[1]
p2score[0]
p2score[0]
p2score[0]
p2score[1]
p2score[1]
p2score[1]
play er2_3
play er2_2
play er2_1
Figure 5.13
18) Now you should insert the output pads for player1_1, player1_2, player1_3, player2_1, player2_2, player2_3, tie_game, and go_led as described in Tutorial 1. Using the Orthogonal Conduit Tool connect the output pads that correspond to the player scores to signal lines and name the signal lines in the same manner that the output pads were named and use the tool to connect the go_led and tie_game output pads to the goLed_controller (Figure 5.14). Name the signal lines connected to the tie_game and go_led output pads, tie_game and go_led respectively.
Figure 5.14
25
19) Using the Orthogonal Node Tool connect two signal lines to the controller and name the lines reset_counter and enable_delay (Figure 5.15).
Figure 5.15
20) Right click on the goLed_controller where the conduit input line is connected and select Mapper Properties (Figure 5.16).
Figure 5.16
21) Under the General tab, select ‘Input’ in the ‘Type’ box as shown in Figure 5.17.
26
Figure 5.17
22) Under the Mappings tab, enter the I/O name that is present in the conduit line connected to the goLed_controller, then select the corresponding signal name in the conduit, and the click Add to place the mapping into the Existing mappings text box (Figure 5.18). Once you have placed all of the signals in the mapping, click OK.
Figure 5.18
23) Repeat this process for the remaining connections to the goLed_controller. Once the mapping process is complete, the schematic should look similar to the one in Figure 5.19. On the outputs from the goLed_controller, select 'Output' for 'Type' under the General tab when performing mappings.
27
Figure 5.19
24) Create an output pad named vcc_pin and connect the pad to the vcc symbol found in the symbol library. This pin will supply 5V to the external board (Figure 5.20).
Figure 5.20
25) Select all input and output pads and assign the pin numbers as was shown in Tutorial 1. Figure 5.21 shows the pin numbers.
Function UP3 pin assignment Ground GndVcc 217clock 29reset 48p1input 222p2input 208start_game 62player1_1 218player1_2 206player1_3 221tie_game 215player2_1 219player2_2 216player2_3 220go_led 207
Figure 5.21
26) Right click on the goLed_controller and select Create Design File from Selected Block (Figure 5.22).
28
Figure 5.22
27) In the Create Design File from Selected Block dialog box (Figure 5.23) select VHDL File type and check the box labeled Add the new design file to the current project. Ensure that the File name is goLed_controller.vhd and click OK.
Figure 5.23
28) A dialog box will appear stating the design file was created (Figure 5.24). Click 'OK' to continue.
Figure 5.24
29
29) Once OK is click from the previous step, VHDL code will appear for the goLed_controller. Edit the VHDL code that corresponds to the state machine shown in Figure 5.25.
NOTE: The code used by LMN Technologies to create the initial design is located in Appendix A of this document.
S0
S3
S2
S1
S4
S6
S8
S10
S12
S14
S16
S5
S7
S9
S11
S13
S15
S17
Reset
tie_game, RESET_DELAY
tie_game="1"
START
START_DELAY,tie_game="1"
END_DELAY
GO_LED, tie_game
p2input
p2score="01", RESET, DELAY
p1input
START
START_DELAY,p2score="01"
END_DELAY
GO_LED,p2score="01"
p2input
RESET_DELAY,p2score="10"
START
START_DELAY,p2score="10"
END_DELAY
GO_LED,p2score="10"
p2input
p1input
RESET_DELAY,p2score="11"
START
p1score="01", RESET, DELAY
START
START_DELAY,p1score="01"
END_DELAY
GO_LED,p1score="01"
p1input
RESET_DELAY,p1score="10"
START
START_DELAY,p1score="10"
END_DELAY
GO_LED,p1score="10"
p1input
p2input
RESET_DELAY,ps1core="11"
p2input
START
START
p1input
Figure 5.25
30
5.1 LMN Technologies Pseudo-Random Delay for “GO LED” VHDL Design Now the schematic is ready to have a setup added using digital logic components that will add a pseudo-random delay that will control the end_delay signal. We at LMN Technologies implemented the delay using a setup of 6 counters as shown below.
25
lpm_and0
inst16
up counterclock
cnt_enac
lrq[24..0]
lpm_counter1
inst14
clock
enable_delay
reset_counter
count_enable
NOT
inst26
NOT
inst27AND3
inst28
reset_counter
p2score[0]2xDelay
clock up counterclock
clk_encnt_en
aclr
q[2..0]
lpm_counter2
inst20
count_enable
NOT
inst30AND3
inst31
reset_counter
p2score[1]7xDelay
clock up counterclock
clk_encnt_en
aclr
q[2..0]
lpm_counter2
inst21
count_enable
NOT
inst32
AND3
inst33
reset_counter
p1score[0]6xDelay
clock up counterclock
clk_encnt_en
aclr
q[2..0]
lpm_counter2
inst22
count_enable
AND3
inst34NOT
inst35
reset_counter
p1score[1]3xDelay
clock up counterclock
clk_encnt_en
aclr
q[2..0]
lpm_counter2
inst23
count_enable
IN1
IN3
IN2
IN5
IN4 OUT
OR5
inst29
end_delay
3xDelay
6xDelay
8xDelay
2xDelay
7xDelay
This concludes the “GO LED” VHDL implementation tutorial. You can now see the effects of the VHDL code on the UP3 development board. You have now interfaced the UP3 to the breadboard LEDs and pushbuttons via a ribbon cable.
3
lpm_and2
inst24
reset_counter
tie_game8xDelay
clock up counterclock
clk_encnt_en
aclr
q[2..0]
lpm_counter2
inst19
count_enable
31
6 Tutorial 3: “GO LED” Implemented Using NIOS II Processor This tutorial will show you the basics of placing the Nios II soft-core processor onto an Altera FPGA. You will then use the Nios II IDE to write and compile C code that will run on the Nios II Processor. Your code should mimic the functionality of the “GO LED” VHDL design from Tutorial 2. We have divided this tutorial into several sections, depending on which program you are using at the time.
6.1 Quartus II – Part 1 You should be familiar with the Quartus II IDE from your experience in Tutorial 1. If you have not done Tutorial 1, we suggest that you do it before proceeding.
1) Browse to the “C:\altera\qdesigns42\” directory. 2) Place the ‘nios2_tutorial’ folder that we provided on your CD into this directory. 3) Open the Quartus II software using Start->Programs->Altera->Quartus 4.2 4) Click ‘File->Open Project’. 5) Browse to the “C:\altera\qdesigns42\nios2_tutorial” directory and select the ‘nios2_tutorial.qpf’
file. 6) This will open the tutorial project as well as a schematic. If the schematic does not appear, select
‘File->Open’ and opening the ‘nios2_tutorial.bdf’ file. Make sure the ‘Add file to current project’ box is checked when you do this.
7) Now select the ‘Tools’ menu and click on ‘SOPC Builder’.
6.2 SOPC Builder SOPC Builder is a program that allows the user to specify what pieces of their board they are going to use and how they are connected. We will construct a system with a Nios II Processor, a JTAG cable, some external RAM, and two parallel input/output devices.
1) The program will prompt you with a dialog shown in Figure 6.1. Enter “nios2_top” as the ‘System Name’ and select ‘VHDL’ as your ‘HDL Language’.
Figure 6.1
2) Near the top of the program, make sure that your target board is ‘Unspecified Board’ and that your clock signal is 48.0 MHz, as shown in Figure 6.2.
32
Figure 6.2
3) In the left-hand component pane, right-click on ‘Nios II Processor – Altera Corporation’ and then click ‘Add New Nios II Processor – Altera Corporation’ to add it to your system. Figure 6.3 shows an example of this action.
Figure 6.3
4) SOPC Builder will prompt you with the dialog shown in Figure 6.4. Select the ‘Nios II/S’ and click ‘Finish’
33
Figure 6.4
5) Under the ‘Bridges’ heading in the left pane, add an ‘Avalon Tri-State Bridge’. This bridge is a bus that will allow the Nios II processor to communicate with the UP3’s on-board RAM. This RAM is external to the FPGA.
6) A dialog will appear. Select ‘Registered’ and click ‘Finish’. 7) Under the ‘Communications’ heading, add a ‘JTAG UART’. This represents our JTAG download
cable. Accept the default settings by clicking ‘Finish’. 8) Under the ‘Memory’ heading, add ‘SLS_UP3_SRAM’. This is our external RAM. Accept the
default settings by clicking ‘Finish’. 9) Under the ‘Other’ heading, add a new ‘PIO (Parallel I/O)’. 10) The dialog shown in Figure 6.5 will appear. Specify 8 bits and ‘Output ports only’.
34
Figure 6.5
11) Click ‘Finish’. 12) SOPC Builder will name this component ‘pio_0’. Rename it ‘led_pio’ by right clicking on it and
selecting ‘Rename’. 13) Add a second ‘PIO’. This time, specify 2 bits and ‘Input ports only’. Click ‘Finish’ 14) Rename this component ‘pushbutton_pio’. 15) Your window should now look similar to Figure 6.6.
Figure 6.6
16) Click the ‘System Generation’ tab. 17) Uncheck the ‘Simulation. Create Modelsim™ project files.’ box, as shown in Figure 6.7.
35
Figure 6.7
18) Click the ‘Generate’ button. The Generate process is not an instantaneous process. After generating the needed files, SOPC Builder will tell you that you can exit the program. However, you should not exit the program at this time. Simply switch your view over to Quartus II. We will return to SOPC Builder later in the tutorial.
6.3 Quartus II – Part 2 You will now finish the design, compile it, and download it onto the FPGA.
1) Your schematic should be open and look like Figure 6.8.
Figure 6.8
2) Click the ‘Symbol Tool’ 3) Inside the Symbol Tool, open the ‘Project’ folder and click on nios2_top. ‘nios2_top’ is a
schematic representation of the system you just created in SOPC Builder. 4) Click ‘OK’ and place this symbol into your schematic. It should fit as shown in Figure 6.9.
36
Figure 6.9
Note that the SRAM_BE[1..0] and ADDr[16..0] wires are connected properly. They do not appear connected in the block diagram. If you look farther to the right in the diagram, you will see two output buffers that have these signals named as their inputs. You can connect wires in this manner using Quartus II.
5) Click the ‘Processing’ menu and then ‘Start Compilation’ 6) Quartus II will be prompt you to save the changes to your block diagram file. Choose yes.
After Quartus has compiled the design, you will see a prompt that displays the number of errors and warnings the design had. Do not be alarmed at the number of warnings you receive. The majority of them fit into two categories. The first category includes warnings that state that certain pins are stuck at VCC or at ground. The design intends for these pins to behave in this manner. The other category relates to the Nios II registers. The tutorial does not use the 32-bit capacity of these registers for this design, so Quartus reduces the size of many of these registers. 7) Click ‘OK’ 8) Click the ‘Tools’ menu and select ‘Programmer’. 9) Check the ‘Program/Configure’ box and click ‘Start’. 10) After Quartus II has programmed the FPGA, switch back to SOPC Builder. 11) Click the ‘Run Nios II IDE’ button shown in Figure 6.10.
Figure 6.10
37
6.4 NIOS II IDE This part of the tutorial will allow you to run C code on the Nios II processor.
1) Click the ‘File’ menu and select ‘New->C/C++ Application’ 2) Name your project ‘nios2_tutorial’. 3) Make sure the ‘Use Default Location’ box is checked. 4) The IDE should automatically fill in the ‘Select Target Hardware’ information as shown in Figure
6.11.
Figure 6.11
5) Select ‘Blank Project’ as your template. 6) Click ‘Finish’ 7) In the left-hand ‘C/C++ Projects’ pane, right-click on the ‘nios2_tutorial’ project and select ‘New-
>File’ 8) Enter ‘nios2_tutorial.c’ in the ‘File name:’ box as shown in Figure 6.12 and click ‘Finish’.
38
Figure 6.12
You will now need to write C code in order to interact with the breadboard LEDs and push buttons. The code that LMN Technologies wrote is included in its entirety in Appendix B. 9) Copy the code shown in Figure 6.13 into your new C file. Some of Altera’s comments are
included that explain why these lines of code are necessary.
39
Figure 6.13
10) Right-click on the ‘nios2_tutorial’ project in the left pane and select ‘Build Project’. This will
generate a “system.h” file that you will need to include in your program. The Nios II IDE generates this file in the “C:\altera\qdesigns42\nios2_tutorial\software\nios2_tutorial_syslib\Debug\system_description\” directory. This file defines your system based on your SOPC Builder components. Find the section that defines your LED_PIO and PUSHBUTTON_PIO components. You will need to know the names of the constants defined here that specify the base address for your PIO’s.
11) You will also need to include the “avalon_pio_regs.h” file in your program. You can view this file in the “C:\altera\kits\nios2\components\altera_avalon_pio\inc\” directory. You will need to use the commands defined in this file to read from and write to your LED PIOs. The prefix “IORD” stands for “Input/Output Read” and “IOWR” stands for “Input/Output Write”. When reading, you supply a function with the base address of the PIO you wish to read. When writing, you supply the base address as well as a value to write. You can use an 8-bit ‘unsigned char’ to hold the values that you read or write to your PIO’s. We suggest storing hexadecimal numbers in the unsigned characters.
Optional Step: You can also include the following file: "C:\altera\kits\nios2\bin\nios2-gnutools\H-i686-pc-cygwin\nios2-elf\include\stdlib.h" if you wish to use C’s random number functions to generate random delays for your design.
12) Now, you will need to code a program that follows the same flow as the VHDL design did. Figure
6.14 has a flow chart that may help you with your coding.
40
Figure 6.14
13) After you finish coding, build the project again. 14) Click on the ‘Run’ menu and select ‘Run…’ 15) Click ‘New’ in the bottom left corner. Figure 6.15 shows the ‘New’ button circled in red.
41
Figure 6.15
16) On the ‘Main’ tab, specify your project as ‘nios2_tutorial’ and name it ‘nios2_tutorial Hardware’. 17) Switch to the ‘Target Connection’ tab and make sure that the ‘Nios II Terminal communication
device’ is set to ‘none’. Figure 6.16 shows this.
Figure 6.16
18) Switch back to the ‘Main’ tab and hit ‘Run’. Once the code is running, the console will display messages similar to those shown in Figure 6.17.
42
Figure 6.17
This concludes the “GO LED” Nios II Processor implementation tutorial. You can now see the effects of the C code on the UP3 development board. You have now interfaced the UP3 to the breadboard LEDs and pushbuttons via a ribbon cable. You have also successfully implemented an embedded system using some simple C code.
43
Appendix A: LMN Technologies “GO LED” VHDL Code -- WARNING: Do NOT edit the input and output ports in this file in a text -- editor if you plan to continue editing the block that represents it in -- the Block Editor! File corruption is VERY likely to occur. -- Copyright (C) 1991-2004 Altera Corporation -- Any megafunction design, and related netlist (encrypted or decrypted), -- support information, device programming or simulation file, and any other -- associated documentation or information provided by Altera or a partner -- under Altera's Megafunction Partnership Program may be used only -- to program PLD devices (but not masked PLD devices) from Altera. Any -- other use of such megafunction design, netlist, support information, -- device programming or simulation file, or any other related documentation -- or information is prohibited for any other purpose, including, but not -- limited to modification, reverse engineering, de-compiling, or use with -- any other silicon devices, unless such use is explicitly licensed under -- a separate agreement with Altera or a megafunction partner. Title to the -- intellectual property, including patents, copyrights, trademarks, trade -- secrets, or maskworks, embodied in any such megafunction design, netlist, -- support information, device programming or simulation file, or any other -- related documentation or information provided by Altera or a megafunction -- partner, remains with Altera, the megafunction partner, or their respective -- licensors. No other licenses, including any licenses needed under any third -- party's intellectual property, are provided herein. -- Generated by Quartus II Version 4.2 (Build Build 157 12/07/2004) -- Created on Sat Mar 19 11:53:05 2005 LIBRARY ieee; USE ieee.std_logic_1164.all; -- Entity Declaration ENTITY game_controller IS -- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! PORT ( clock : IN STD_LOGIC; reset : IN STD_LOGIC; p1input : IN STD_LOGIC; p2input : IN STD_LOGIC; start_game : IN STD_LOGIC; end_delay : IN STD_LOGIC; enable_delay : OUT STD_LOGIC; go_led : OUT STD_LOGIC; reset_counter : OUT STD_LOGIC;
44
p1score : OUT STD_LOGIC_VECTOR(1 downto 0); p2score : OUT STD_LOGIC_VECTOR(1 downto 0); tie_game : OUT STD_LOGIC ); -- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! END game_controller; -- Architecture Body ARCHITECTURE game_controller_architecture OF game_controller IS type state_type is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17); signal state: state_type; BEGIN process(clock,reset,p1input,p2input,start_game,end_delay) begin if reset='0' then state<=s0; elsif clock'event and clock='1' then case state is when s0=> state<=s1; when s1=> if start_game='0' then state<=s2; else state<=s1; end if; when s2=> if end_delay='1' then state<=s3; else state<=s2; end if; when s3=> if p1input='0' then state<=s4; elsif p2input='0' then state<=s5; else state<=s3; end if; when s4=> if start_game='0' then state<=s6; else state<=s4; end if; when s5=> if start_game='0' then state<=s7; else state<=s5; end if; when s6=> if end_delay='1' then state<=s8; else state<=s6; end if; when s7=> if end_delay='1' then state<=s9; else state<=s7; end if; when s8=> if p1input='0' then state<=s10; elsif p2input='0' then state<=s1; else state<=s8; end if;
45
when s9=> if p2input='0' then state<=s11; elsif p1input='0' then state<=s1; else state<=s9; end if; when s10=> if start_game='0' then state<=s12; else state<=s10; end if; when s11=> if start_game='0' then state<=s13; else state<=s11; end if; when s12=> if end_delay='1' then state<=s14; else state<=s12; end if; when s13=> if end_delay='1' then state<=s15; else state<=s13; end if; when s14=> if p1input='0' then state<=s16; elsif p2input='0' then state<=s4; else state<=s14; end if; when s15=> if p2input='0' then state<=s17; elsif p1input='0' then state<=s5; else state<=s15; end if; when s16=> if reset='0' then state<=s0; else state<=s16; end if; when s17=> if reset='0' then state<=s0; else state<=s17; end if; when others=> state<=s0; end case; end if; end process; process(state) -- *** Must Assign following signals in each state *** -- enable_delay : OUT STD_LOGIC; -- go_led : OUT STD_LOGIC; -- reset_counter : OUT STD_LOGIC; -- p1score : OUT STD_LOGIC_VECTOR(1 downto 0); -- p2score : OUT STD_LOGIC_VECTOR(1 downto 0); -- tie_game : OUT STD_LOGIC begin if state=s0 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="00";
46
p2score<="00"; tie_game<='0'; elsif state=s1 then reset_counter<='0'; enable_delay<='0'; go_led<='0'; p1score<="00"; p2score<="00"; tie_game<='1'; elsif state=s2 then reset_counter<='0'; enable_delay<='1'; go_led<='0'; p1score<="00"; p2score<="00"; tie_game<='1'; elsif state=s3 then reset_counter<='0'; enable_delay<='0'; go_led<='1'; p1score<="00"; p2score<="00"; tie_game<='1'; elsif state=s4 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="01"; p2score<="00"; tie_game<='0'; elsif state=s5 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="00"; p2score<="01"; tie_game<='0'; elsif state=s6 then reset_counter<='0'; enable_delay<='1'; go_led<='0'; p1score<="01"; p2score<="00"; tie_game<='0'; elsif state=s7 then reset_counter<='0'; enable_delay<='1'; go_led<='0'; p1score<="00"; p2score<="01";
47
tie_game<='0'; elsif state=s8 then reset_counter<='0'; enable_delay<='0'; go_led<='1'; p1score<="01"; p2score<="00"; tie_game<='0'; elsif state=s9 then reset_counter<='0'; enable_delay<='0'; go_led<='1'; p1score<="00"; p2score<="01"; tie_game<='0'; elsif state=s10 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="10"; p2score<="00"; tie_game<='0'; elsif state=s11 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="00"; p2score<="10"; tie_game<='0'; elsif state=s12 then reset_counter<='0'; enable_delay<='1'; go_led<='0'; p1score<="10"; p2score<="00"; tie_game<='0'; elsif state=s13 then reset_counter<='0'; enable_delay<='1'; go_led<='0'; p1score<="00"; p2score<="10"; tie_game<='0'; elsif state=s14 then reset_counter<='0'; enable_delay<='0'; go_led<='1'; p1score<="10"; p2score<="00"; tie_game<='0';
48
elsif state=s15 then reset_counter<='0'; enable_delay<='0'; go_led<='1'; p1score<="00"; p2score<="10"; tie_game<='0'; elsif state=s16 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="11"; p2score<="00"; tie_game<='0'; elsif state=s17 then reset_counter<='1'; enable_delay<='0'; go_led<='0'; p1score<="00"; p2score<="11"; tie_game<='0'; end if; end process; END game_controller_architecture;
49
Appendix B: LMN Technologies “GO LED” C Code #include "system.h" #include "altera_avalon_pio_regs.h" #include "C:\altera\kits\nios2\bin\nios2-gnutools\H-i686-pc-cygwin\nios2-elf\include\stdlib.h" //function headers void delayed_blink(unsigned char led); void random_delay(unsigned char led); void intro(); void player1win(); void player2win(); /* * This is a freestanding application, so we want to use alt_main * as the entry point. However, if the debugger is run on this * application, it will try to set a breakpoint at main, which * the application does not contain. The below line creates an * alias so the debugger is able to set a breakpoint at main, * yet the application retains alt_main as it's entry point. */ int main (void) __attribute__ ((weak, alias ("alt_main"))); /* * Use alt_main as entry point for this free-standing application */ int alt_main (void) { unsigned char led; unsigned char pushbutton; /* the variable 'led' represents the 8 bit led_pio component you * placed in SOPC Builder. Here are the relationships of the * individual led_pio signals to the VHDL signals you used in * an earlier tutorial * * led_pio[0] = go_led * led_pio[1] = player2_3 * led_pio[2] = player2_2 * led_pio[3] = player2_1 * led_pio[4] = tie_game * led_pio[5] = player1_1 * led_pio[6] = player1_2 * led_pio[7] = player1_3 */ intro(); //flashes leds in a pattern to signal that //the game is about to start led = 0x10; //sets the middle LED up IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); random_delay(led); //starts the first round. the tie_game and go_led LEDs will be lighted led = led ^ 0x01; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led);
50
while (1) { //this loop will run until one player presses their pushbutton while(1){ //read the pushbutton pio pushbutton = IORD_ALTERA_AVALON_PIO_DATA(PUSHBUTTON_PIO_BASE); //if player 1 presses his button first, we shift the score //in his direction if(pushbutton == 0x2){ led = led ^ 0x01; //toggle go_led off led = led << 1; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); break; } //if player 2 presses his button first, we shift the score //in his direction else if(pushbutton == 0x1){ led = led ^ 0x01; //toggle go_led off led = led >> 1; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); break; } } //if the final led on player 1's side of the board is reached, //he wins if(led == 0x02){ player1win(); break; } //if the final led on player 2's side of the board is reached, //he wins else if(led == 0x80){ player2win(); break; } random_delay(led); //toggle go_led on led = led ^ 0x01; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); } while(1); return 0; } void random_delay(led) unsigned char led; { unsigned int seed; if(led == 0x10) seed = 5; else if(led == 0x20) seed = 50; else if(led == 0x40) seed = 500; else if(led == 0x08) seed = 5000; else if(led == 0x04) seed = 50000; else if(led == 0x02)
51
seed = 500000; else seed = 1000; int rand = rand_r(&seed); rand = rand % 10000000; rand += 200000; while(rand > 0){ rand--; } } void intro(){ unsigned char led = 0x01; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); led = led << 1; delayed_blink(led); delayed_blink(0x00); delayed_blink(0xFF); delayed_blink(0x00); delayed_blink(0xFF); return; } void player1win(){ delayed_blink(0x0E); delayed_blink(0x00); delayed_blink(0x0E); delayed_blink(0x00); delayed_blink(0x0E); delayed_blink(0x00); delayed_blink(0x0E); delayed_blink(0x00); return; } void player2win(){ delayed_blink(0xE0); delayed_blink(0x00); delayed_blink(0xE0); delayed_blink(0x00); delayed_blink(0xE0); delayed_blink(0x00); delayed_blink(0xE0); delayed_blink(0x00); return; } void delayed_blink(led) unsigned char led;
52
{ int count = 0; while(count < 200000) count++; IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, led); }