I recently purchased a Terasic DE2-70 Cyclone II development board. The makers have two prices: $599 commercial and $349 academic. If you’re a college student, the academic price is still too much. After I got a job, made some money, and saved up, I sent the Taiwanese company Terasic a little email. I told them I recently graduated and wanted to get the academic price, stating that I would be using it for personal learning, etc. They were more than happy to offer the discount, so I’m now the proud owner of a DE2-70. (By the way, they ship from Taiwan – viz. $40 shipping from the other side of the world.)
Well, having gone through Altera’s “Introduction to the Altera SOPC Builder Using VHDL Design” to remember how to use the software, I found multiple problems with the tutorial as it is. I hope that listing the solutions here will help people in the same situation. Some of these issues are obvious, and some are a bit more subtle.
I am using Quartus II 7.2 and NiosII 7.2.
- In Step 1: “In your project, choose the EP2C35F672C6 chip as the target device, because this is the FPGA on the DE2 board”. Well, the DE2-70 uses a different chip. Choose the EP2C70F896C6. This can be verified by simply looking at the text printed on the FPGA.
- In Step 1: “You can choose a different directory or project name, but be aware that the SOPC Builder software does not permit the use of spaces in file names”. This is true and I just wanted to make it obvious that you can’t have a space *anywhere* in the pathname. For example, you would have problems in SOPC Builder if your project was in “C:\Program Files\…” since that path contains a space.
- In Step 6: “In the On-Chip Memory Configuration Wizard window, shown in Figure 8, set the memory width to 32 bits and the total memory size to 4 Kbytes”. As I’ll be getting to shortly, the 4kB is not enough for the NiosII project. Crank it up to 64kB for plenty of breathing room.
- In Step 7: The PIO is under Peripherals -> Microcontroller Peripherals -> PIO (Parallel I/O).
- In Step 9: The JTAG UART is under Interface Protocols -> Serial -> JTAG UART.
- After Step 11: Write down the base addresses of the PIOs after auto-assigning the addresses. These will be needed for NiosII, as they are treated as memory-mapped I/O.
- Before Step 12: There are a couple “To Do”‘s in the message window of SOPC Builder about the NiosII CPU that need to be addressed: the reset and exception vectors. Double-click the NiosII component you instantiated to open up the properties window you were at before. Now that you have on-chip memory instantiated, click on the Reset Vector and Exception Vector Memory drop-down boxes and select the name of your memory (e.g. “onchip_mem”). Leave the offsets the way they are (0x0 and 0x20). Don’t worry about the “Warning: Switches: PIO inputs are not hardwired in test bench. Undefined values will be read from PIO inputs during simulation.”, this tutorial doesn’t do any test benches.
- Importing DE2_70_pin_assignments.csv. This comma-separated file is located on the DE2-70 CD included with the kit, and it can also be found on the internets. Mmm, google. The naming convention for this Altera-supplied file changed from DE2 to DE2-70. Open it and take a look. There are now lower-case ‘i’s and ‘o’s before many of the hard-wired signals denoting them as input and output. Remember this! The HDL code needs to change reflecting this. Otherwise the .csv needs changing, but I don’t suggest it. Here’s my resulting code (remember, the port names may be different for your SOPC component):
- LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;ENTITY lights IS
PORT (
iSW : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
iKEY : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
iCLK_50 : IN STD_LOGIC;
oLEDG : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END lights;ARCHITECTURE Structure OF lights IS
COMPONENT nios_system is
port (
— 1) global signals:
signal clk : IN STD_LOGIC;
signal reset_n : IN STD_LOGIC;— the_LEDs
signal out_port_from_the_LEDs : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);— the_Switches
signal in_port_to_the_Switches : IN STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END COMPONENT;BEGIN
NiosII: nios_system PORT MAP(iCLK_50, iKEY(0), oLEDG, iSW);
END Structure;
- LIBRARY ieee;
- Before Section 3.2: If you’ve tried to do a full compilation at this point, you will probably see an unexpected error:
- Error: Can’t place pins assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)
Info: Pin iSW[7] is assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)
Info: Pin ~LVDS195p/nCEO~ is assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)
Error: Can’t fit design in device
Error: Quartus II Fitter was unsuccessful. 2 errors, 3 warnings
Info: Allocated 215 megabytes of memory during processing
Error: Processing ended: Sun Oct 18 19:11:13 2009
Error: Elapsed time: 00:00:03
Error: Quartus II Full Compilation was unsuccessful. 2 errors, 152 warnings - Here is the fix:
- In Quartus-II select menu Assignments>Device…
- Select button “Device and Pin Options…”
- Select the tab “Dual-Purpose Pins”
- Under the list of “Dual-purpose pins:” change the “Value” property of nCEO to “Use as regular I/O”.
- Click OK
- Error: Can’t place pins assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)
- After Section 3.2: If you are using the Web edition or didn’t buy the full license for the Altera IP, you probably got a pop-up window after programming the device stating “OpenCore Plus Status Click Cancel to stop using OpenCore Plus IP. Time remaining: unlimited”. Do not close this window if you intend on using the NiosII IDE to run on the hardware. Just leave the window up and close when you are done, or have a problem with Quartus or SOPC Builder.
- I skipped over the Assembly programming section because this tutorial already gave me a headache. I’m not a masochist.
- In Section 4.2: When you create a new project, create it in the following way: File -> New -> Project… and select “Nios II C/C++ Application”. Also, use the Hello World template. It sets everything up for you, gives you printf functionality to the console, but takes up a bit more space.
- lights.c: Here’s what I have in my file. Again, it might be a bit different for the base addresses.
- #include <stdio.h>
#define Switches (volatile char*) 0x21000
#define LEDs (char*) 0x21010int main()
{
printf(“Hello from Nios II!\n”);
while (1){
*LEDs = *Switches;
}
return 0;
}
- #include <stdio.h>
- After all of that is done, you right-click on your project in NiosII IDE (e.g. hello_world_0) and click “Run As -> Nios II Hardware”.
- Done! You can now move the switches (SW7 – 0) and see the LEDG7-0 change. You can also reset the CPU using KEY0.
I know how frustrating it can be trying to learn something when the tutorial is wrong. Hope this helps!