Abstract
本文使用Quartus II、SOPC Builder、Nios II EDS從0開始打造一個能在DE2-70上跑μC/OS-II的Nios II系統,初學者可借此範例熟悉Quartus II、SOPC Builder、Nios II EDS的使用,並且了解基於FPGA的嵌入式系統開發流程。
Introduction
使用環境:Quartus II 8.1 + Nios II EDS 8.1 + DE2-70 (Cyclone II EP2C70F896C6N)
這4篇原本是設計在一起的lab,適合初學者從0開始慢慢熟悉Quartus II、SOPC Builder、Nios II EDS、Avalon Bus Slave、Avalon Bus Master。
(原創) 如何自己用SOPC Builder建立一個能在DE2-70上跑μC/OS-II的Nios II系統? (SOC) (Quartus II) (SOPC Builder) (Nios II) (μC/OS-II) (DE2-70)
(原創) 如何設計一個七段顯示器Controller? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)
(原創) 如何設計一個SD卡Wav Player? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)
(原創) 如何設計一個數位相框? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)
(很多人應該早已在http://quest.ee.ntu.edu.tw/jenny/homepage/sdwang_codesign2008/Lab1-ucos-ii/Lab1.html這個網址看過這篇教學,其實這篇是我在學校當助教時所寫的Lab,這個Lab共有4篇教學,這篇只是第1篇而已,我將陸續將剩下3篇也公佈在blog上。由於年代有點久遠,當時是在Quartus II 8.1上實驗,並不保證在未來的Quartus II版本能正常執行,若遇到Nios II規格變動,或者Quartus II timing的問題,請您自行調試)
為什麼要從0開始建立一個Nios II系統呢?
1.可以自行對SOPC做最佳化。
2.很多範例都是純硬體的Verilog code,需要自行從0開始建立Nios II系統,不能再使用Altera或友晶科技所建立好的Nios II系統。
3.DE2-70並非Altera原廠的開發版,而是友晶科技ODM的版子,很多周邊都與Altera原廠的版子不一樣,所以很多Altera手冊中範例都無法執行,必須要有自己從硬體到軟體建立系統的能力,將來才有辦法將Altera原廠的範例移植到DE2-70上執行並做最佳化。
DE2-70開發版
DE2-70系統架構圖
本範例系統架構圖
最後結果希望在μC/OS-II下實現多執行緒執行,並且LEDG[17:0]能透過軟體被SW[17:0]控制。
Quartus II部分
使用Quartus II建立一個全新的project
Step 1:
建立一個新project
Step 2:
Introduction
按Next繼續。
Step 3:
輸入project路徑名稱、project名稱與top module名稱
按Next繼續。
Step 4:
c:/DE2-70/hello_ucosii目錄尚未建立,是否建立此目錄
按是(Y)繼續。
Step 5:
加入既有檔案到project,
由於我們目前還沒有建立任何檔案,所以按Next繼續。
Step 6:
選擇FPGA型號
DE2-70使用的FPGA是Cyclone II EP2C70F896C6N,由Altera對FPGA的命名規則可得知:
EP2C:Cyclone II
70:70家族
F:FBGA
896:896 pin
C6:speed grade 6
按Next繼續。
Step 7:
選擇3rd Party的EDA工具
Quartus II支援3rd Part的EDA工具,如ModelSim,若有用到可在此設定,目前沒用到,按 Next繼續。
Step 8:
最後的Summary
按Finish完成。
SOPC Builder部分
使用SOPC Builder建立一個全新的Nios II系統
Step 9:
啟動SOPC Builder
Step 10:
輸入System name,並選擇Verilog
選擇Verilog,表示SOPC Builder會將你稍後所設定的ip,以Verilog表示,若你熟悉VHDL,也可以選擇VHDL。這理的設定不限制你日後只能用Verilog或VHDL寫code,因為Quartus II本來就允許你Verilog與VHDL混合編程,也就是說Verilog的module可以使用VHDL的entity,VHDL的entity可以使用Verilog的module,最後都能順利編譯。
注意左上角Device Family為Cyclone II,且右上角clk_0為50.0Mhz,雖然Nios II在DE2-70可以只跑50.0MHz,但這等於是CPU降頻在跑,正常情況下,Nios II在DE2-70可以跑100.0MHz,所以我們接著打算用PLL將clk倍頻成100.0Mhz。
Step 11:
加入PLL
產生Nios II CPU與SDRAM所需要的clk,在左側用滑鼠按兩下PLL加入SOPC。
Page1
接受預設值即可,按Next繼續。
Page2
接受預設值即可,按Next繼續。
Page3
接受預設值即可,按Next繼續。
Page4
設定CPU所需要的100MHz clk,將Clock multiplication factor設為2,注意Actual settings出現100.000000Mhz。
使用ALTPLL產生clk有一點需注意,並不是任何clk都可以產生,若ATLPLL可以合成的clk,會在上方出現Able to implement the requested PLL。
按Next繼續。
Page5
設定SDRAM所需要的100MHz clk,但必須有-65度的phase shift。
按Next繼續。
Page 6
不再需要其他clk,按Next繼續。
Page 7
接受預設值即可,按Next繼續。
Page 8
接受預設值即可,按Finish完成。
最後按Finish完成。
最後會出現pll_0: pll_0.s1 must be connected to an Avalon-MM master的錯誤訊息,因為pll_0是個slave ip,必須被動的受master ip控制,稍後等到SOPC加入了master ip(此系統就是Nios II CPU)後,就可解決。
Step 12:
更改clk名稱
將clk改成有意義的名稱。
clk_0改成clk_50。
pll_0_c0改成cpu_clk。
pll_0_c1改成sdram_clk。
pll_0改成pll。
Step 13 :
加入Nios II CPU
根據用戶需要選擇Nios II Core:
1.Nios II/e (economic):占用LE最少,功能最少,速度最慢。
2.Nios II/s (standard):速度與LE平衡,具有Nios II CPU一般功能。
3.Nios II/f (full):占用LE最多,功能也最多,速度最快。
本範例選用Nios II/f。
Reset Vector與Exception Vector暫時不需設定,因為還未將記憶體ip掛上,最後再設定。
其他設定接受預設值即可,按Finish完成
將cpu_0改成cpu。
因為Nios II CPU的加入,而Nios II CPU就是個典型的master ip,SOPC自動將將cpu(master)與pll(slave)相連,因此pll_0: pll_0.s1 must be connected to an Avalon-MM master錯誤訊息不見了。
新增的warning是剛提到的reset vector與exception vector,最後再設定。
Step 14:
加入On-Chip Memory
FPGA內少量的M4K記憶體,是DE2-70所有記憶體中速度最快,不過容量最小的記憶體。
設定30 KBytes的On-chip Memory。
Total memory size與能使用的M4K記憶體數量有關。不同的FPGA型號有關、選擇不同的Nios II CPU Core、使用Megafunction(如fcfifo)都會影響On-chip Memory的size。
將onchip_memory2_0改成onchip_mem。
出現2個cannot be at 0x1000的錯誤訊息是正常的,因為SOPC Builder初步為onchip_mem的定址0x1000並不合法,等所有ip都加入後,最後會一併重新對所有slave ip定址。
Step 15:
加入SSRAM的Tristate Bridge
因為SSRAM與Flash的databus是tristate,所以Nios II CPU與SSRAM、Flash相接時需要透過Tristate Bridge。
接受預設值即可,按Finish完成。
將tri_state_bridge_0改成tristate_bridge_ssram。
出現了tristate_bridge_ssram: tristate_bridge_ssram.tristate_master must connected to Avalon-MM Tristate slave的錯誤訊息,因為tristate_bridge_ssram的master interface需要與slave ip相連,下一步加上SSRAM controller後,就可以解決此問題。
Step 16:
加入SSRAM
接受預設值即可,按Finish完成。
將ssram_0改成ssram。
將ssram與tristate_bridge_ssram相連,這樣就可解掉tristate_bridge_ssram: tristate_bridge_ssram.tristate_master must connected to Avalon-MM Tristate slave錯誤訊息。
SSRAM是DE2-70上速度僅次於On-chip Memory的記憶體,且容量從DE2的512KB進步到2MB,實用性大增。大部分的軟體跑在SSRAM都相當足夠。
Step 17:
加入Flash的Tristate Bridge
如同Step 15加入一個Tristate Bridge,並將名稱改成tristate_bridge_flash
Step 18:
加入Flash
在Attribute這一頁,將Address Width設為22,Data Width設為16。
在Timing這一頁,將Wait設為100。按Finish完成。
將cfi_flash_0改成cfi_flash。
將cfi_flash與tristate_bridge_flash相連,這樣就可解掉tristate_bridge_flash: tristate_bridge_flash.tristate_master must connected to Avalon-MM Tristate slave錯誤訊息。
多了cpu.instruction_master: onchip_mem.s1 (0x1000..0x8fff) overlaps cfi_flash.s1(0x0..0x7fffff) 與 cpu.data_master: onchip_mem.s1 (0x1000..0x8fff) overlaps cfi_flash.s1(0x0..0x7fffff) 兩個錯誤訊息,因為SOPC Builder為cfi_flash初步的定址0x00000000..0x007fffff已經與onchip_mem的0x00001000..0x000087ff相重疊,等所有controler都加入後,最後會一併重新對所有controller定址。
Flash為DE2-70上唯一斷電後仍保存資料的記憶體,若想Nios II程式斷電後,一通電就可以執行,就要將軟體放在Flash上。
Step 19:
加入SDRAM
在Memory Profile這一頁,設定
Presets : Custom
Data width : 32
Chip select : 1
Banks : 4
Row : 13
注意最後Memory size為64MBytes。
在Timing這一頁,設定
Issue one refresh command every: 7.8125 us
Delay after powerup, before initialization : 200 us
將sdram_0改成sdram。
一樣會出現sdram base address的錯誤訊息,最後會一併解決。
Step 20:
加入JTAG UART
JTAG UART是PC與SOPC進行序列傳輸的一種方式,也是Nios II標準的輸出/輸入設備。如printf()透過JTAG UART,經過USB Blaster將輸出結果顯示在PC的Nios II EDS上的console,scanf()透過USB Blaster經過JTAG UART將輸入傳給SOPC的Nios II。
接受預設值即可,按Finish完成。
將jtag_uart_0改成jtag_uart。
Step 21:
加入UART(RS-232 Serial Port)
UART是PC與SOPC進行序列傳輸的另一種方式,也是Nios II標準的輸出/輸入設備。如printf()也可透過UART,經過RS232將輸出結果顯示在PC的Nios II EDS上的console,scanf()也可透過RS232經過UART將輸入傳給SOPC的Nios II。
將Include CTS/RTS pins and control register bits打勾,其他接受預設值即可,按Finish完成。
將uart_0改成uart。
Step 22:
加入Timer
此處要加入2個timer,一個做為system clock,一個做為timestamp。尤其μC/OS-II一定需要timestamp timer,否則無法執行。
接受預設值即可,按Finish完成。
將timer_0改成sys_clk_timer
重複相同的步驟,加入timestamp_timer。
Step 23:
加入System ID
SOPC Builder會使用System ID為每個系統提供識別符號,Nios II EDS可以此防止使用者燒錄了與*.ptf不符合的*.sof。
接受預設值即可,按Finish完成。
將sysid_0改成sysid。
(一定要將名稱改成sysid,因為Nios II EDS將會使用sysid做判斷,否則會產生錯誤。)
Step 24:
加入Character LCD
為DE2-70上的16 x 2字元型LCD,可做為Nios II的標準輸出設備。如printf()也可透過Character LCD將字串顯示在LCD上。
接受預設值即可,按Finish完成。
將lcd_0改成lcd。
Step 25:
加入LED PIO
此處要加入2個LED PIO,一個為LEDG,一個做為LEDR。
LEDG
因為LEDG[8:0]且僅用於輸出,所以width設為9,且選擇Output ports only,按Finish完成。
將pio_0改成pio_ledg。
LEDR
如同增加LEDG PIO的方式加入LEDR PIO。
因為LEDR[17:0]且僅用於輸出,所以width設為9,且選擇Output ports only,按Finish完成。
將pio_0改成pio_ledr。
Step 26:
加入Input PIO
此處要加入2個Input PIO,一個為KEY,一個做為SW。
KEY
如同Step 25一樣,選擇PIO(Parallel I/O)。
因為KEY[3:0]且僅用於輸入,所以width設為4,且選擇Input ports only,按Finish完成。
將pio_0改成pio_key。
SW
因為SW[17:0]且僅用於輸入,所以width設為18,且選擇Input ports only,按Finish完成。
將pio_0改成pio_sw。
Step 27:
重新設定Base Address
之前很多error與warning都是因為都是因為controller的base address重複,目前已經將所有用到的controller加到SOPC Builder,可以讓SOPC Builder重新設定base address。
錯誤訊息都不見了。
Step 28:
設定Nios II CPU的Reset Vector與Exception Vector
在Step 13設定Nios II CPU時,因為當時還沒有掛上任何記憶體,所以當時還沒設定Reset Vector與Exception Vector,現在回頭設定。
簡單的說,reset vector就是當系統reset時,CPU會跳到reset vector所指定的位址執行,所以reset vector所指定的記憶體必須是非揮發性記憶體,在DE2-70只有flash。
而exception vector則是當發生hardware interrupt或software exception時,CPU會跳到exception vector所指定的位址執行,為了更有效率,我們會將exception vector指向速度最快的記憶體,通常是on-chip memory或SSRAM。
最後按Finish完成。
最後完成所有SOPC設定,注意下方只有3條訊息,前2個warning是提醒pio_key與pio_sw需要input testbench,這可以忽略
Step 29:
產生SOPC
按下Generate,正式產生nios_ii.ptf,這需要一點時間產生,依CPU運算速度而定。
按Save將nios_ii.sopc存檔,這個檔記載著所有SOPC Builder的controller與設定值。
約1分半後,SOPC Builder generate成功。
SOPC Builder Generate主要做2件事情。
1.產生nios_ii.ptf檔:
這個檔案將來是Nios II EDS產生用來產生System Library的依據,Nios II軟體與μC/OS-II才能藉此存取SOPC。
2.產生各controller的Verilog檔:
由於SOPC基於FPGA技術,最後必須由Quartus II產生*.sof檔燒到FPGA內,SOPC Builder會產生controller的Verilog code供Quartus II編譯。你可以發現project的根目錄多了很多*.v,這就是SOPC Builder所產生的。
Top Module部分
SOPC Builder為我們產生了各controller的module後,需要有一個top module使之與DE2-70的I/O port相連。
Step 30:
建立Top Mudule
在C:\DE2-70\hello_ucosii\建立hardware目錄。
下載Lab1_files.zip,其中的hello_ucosii.v是一個未完成的top module,將hello_ucosii.v與Reset_Delay.v放在C:\DE2-70\hello_ucosii\目錄下。
有4個地方必須修改後,才能完成top module。
256行
改成
217行
改成
229行
改成
因為DE2-70有2顆SDRAM,所以要assign兩次clk。
277行
改成
因為DRAM_DQ是inout型態,不能使用wire連接,要直接連到inout port。
要如何知道SOPC System有哪些port呢?
開啟nios_ii.v,這是由SOPC Builder所產生的Verilog code,搜尋『module nios_ii (』,可以找到SOPC System的module定義,top module就是根據這裡的定義,連到DE2-70的I/O port。
Step 31:
設定Reserved all unused pins As input tri-stated
Assignment -> Device
Device and Pin Options...
Unused Pins : Reserve all unused pins: As input tri-stated
這個步驟一定要做,否則Nios II無法執行,會出現以下錯誤訊息,初學者常常忽略這個步驟!!
Step 32:
Import Pin Assignment
下載Lab1_files.zip,其中的DE2_70_pin_assignments.csv記錄了DE2-70所有 I/O的連接腳位。
Assignments -> Import Assignments...
載入DE2_70_pin_assignments.csv,按OK繼續。
查看Pin Assignment結果
Assignments -> Assignment Editor
如下圖,表示Pin Assignment設定成功。
這個步驟也一定要做,否則Nios II無法執行,也會出現以下錯誤訊息,初學者常常忽略這個步驟!!
Step 33:
設定nCEO為Use as regular I/O
Assignments –> Device
Device and Pin Options...
Dual-Purpose Pins
將nCEO改成Use as regular I/O
這是DE2-70設計上的問題,在DE2或其他的Altera的開發版並不需要如此設定。若不這樣設定,Quartus II在編譯時會出現以下錯誤訊息而編譯失敗。
Step 34:
Quartus II編譯
需要2到10分鐘的時間,視CPU速度而定。
Programmer部分
使用Programmer將編譯的的*.sof燒進FPGA
Step 35:
啟動Programmer
按Hardware Setup,設定USB-Blaster。
選擇可用的USB-Blaster
按Start開始將*.sof燒進FPGA,當100%出現時,表示燒錄成功。
至目前為止,硬體部分結束,接下來是軟體部分。
Nios II EDS部分
使用Nios II EDS開發Nios II軟體
Step 36:
使用Hello Wrold測試硬體是否設計成功
Quartus II能正常編譯,不代表硬體設計成功,SOPC Builder各controller的參數設定錯誤、clk設定錯誤、top module連線錯誤、Quartus II設定錯誤...等,都可能造成Nios II無法執行,所以先用最簡單的Hello World測試硬體,若連Hello World都不能執行,軟體部分就不用繼續了,先回頭找硬體部分的bug。
右側選擇Hello World template,並指定SOPC Builder System PFT File:c:\DE2-70\hello_ucosii\nios_ii.ptf,這是先前SOPC Builder所generate的ptf檔。最後直接按Finish完成。
Nios II EDS會根據你選的project template與SOPC Builder System File產生2個project:
1.hello_world_0:Nios II Software project。
2.hello_world_0_syslib:Nios II System Library project。(System Library = HAL(Hardware Abstraction Layer) = BSP(Board Support Package) = Driver)
選hello_world_0,按滑鼠右鍵,選System Library Properties
將System clock timer選sys_clk_timer,另外將軟體全部跑在SDRAM,當然也可以跑在其他記憶體,只是因為SDRAM容量最大,而且SDRAM的clk需要phase shift,所以最常出現問題都是在SDRAM,所以在此特別使用SDRAM,至於其他記憶體可自行測試。
Rus As Nios II Hardware,此實Nios II軟體會透過JTAG UART傳到SDRAM開始執行。
若第一次執行,Nios II EDS會編譯整個System Library,需要一點時間,約2到3分鐘。
最後執行結果,Nios II由JTAG UART傳回Hello from Nios II到PC的Console。
若能正確執行Hello World,表示SOPC硬體正確,可以繼續軟體的開發。
Step 37
測試Hello μC/OS-II
目前為止,single thread的軟體程式已經能跑在Nios II上,若要讓Nios II能跑multi thread,就必須靠OS才行,Nios II EDS已經已經巧妙的將μC/OS-II包在System Library裡面。
執行結果
Step 38:
開發一個多執行緒且控制硬體的程式
能成功執行Hello Wrold與Hello μC/OS-II,表示軟硬體都已經設定妥當,可以正式用C寫程式了。
再用Hello μC/OS-II template建立一個project。
將hello_ucosii.c改成如以下的程式
hello_ucosii.c / C
2 # include " includes.h "
3 # include " system.h "
4 # include < io.h >
5
6 /* Definition of Task Stacks */
7 #define TASK_STACKSIZE 2048
8 OS_STK task1_stk[TASK_STACKSIZE];
9 OS_STK task2_stk[TASK_STACKSIZE];
10
11 /* Definition of Task Priorities */
12
13 #define TASK1_PRIORITY 1
14 #define TASK2_PRIORITY 2
15
16 /* Prints "Hello World" and sleeps for three seconds */
17 void task1(void * pdata)
18 {
19 while ( 1 )
20 {
21 printf( " Hello uCOS-II\n " );
22 OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
23 }
24 }
25 /* Prints "Hello World" and sleeps for three seconds */
26 void task2(void * pdata)
27 {
28 unsigned int i;
29 while ( 1 )
30 {
31 // read switch
32 i = IORD(PIO_SW_BASE, 0 );
33 // write ledr
34 IOWR(PIO_LEDR_BASE, 0 , i);
35 }
36 }
37 /* The main function creates two task and starts multi-tasking */
38 int main(void)
39 {
40 OSTaskCreateExt(task1,
41 NULL,
42 (void * ) & task1_stk[TASK_STACKSIZE - 1 ],
43 TASK1_PRIORITY,
44 TASK1_PRIORITY,
45 task1_stk,
46 TASK_STACKSIZE,
47 NULL,
48 0 );
49 OSTaskCreateExt(task2,
50 NULL,
51 (void * ) & task2_stk[TASK_STACKSIZE - 1 ],
52 TASK2_PRIORITY,
53 TASK2_PRIORITY,
54 task2_stk,
55 TASK_STACKSIZE,
56 NULL,
57 0 );
58 OSStart();
59 return 0 ;
60 }
61
62
程式解說
#include < io.h >
system.h記載著SOPC Builder裡各controller的資訊,稍後會討論。
io.h定義了IORD()與IOWR()兩個巨集,可以利用此巨集存取各controller的register。
{
while ( 1 )
{
printf( " Hello uCOS-II\n " );
OSTimeDlyHMSM( 0 , 0 , 3 , 0 );
}
}
void task2( void * pdata)
{
unsigned int i;
while ( 1 )
{
// read switch
i = IORD(PIO_SW_BASE, 0 );
// write ledr
IOWR(PIO_LEDR_BASE, 0 , i);
}
}
i = IORD(PIO_SW_BASE, 0); // 讀取SW目前的值。
IOWR(PIO_LEDR_BASE, 0, i); // 將SW的值馬上給LEDR顯示。
也就是說,若SW為ON時,LEDR會亮,若SW為OFF時,LEDR就不亮。
我們是怎麼做到的呢?
我們透過IORD()巨集,去讀取pio_sw controller目前register的值,然後透過IOWR()巨集,將值寫入pio_ledr controller的register,讓LEDR顯示。
問題來了!!我們怎麼知道pio_sw與pio_ledr在哪裡?
之前#include
開啟C:\DE2-70\hello_ucosii\software\hello_ucosii_1_syslib\Debug\system_description\system.h
459行
#define PIO_SW_TYPE "altera_avalon_pio"
#define PIO_SW_BASE 0x094110c0
#define PIO_SW_SPAN 16
#define PIO_SW_DO_TEST_BENCH_WIRING 0
#define PIO_SW_DRIVEN_SIM_VALUE 0
#define PIO_SW_HAS_TRI 0
#define PIO_SW_HAS_OUT 0
#define PIO_SW_HAS_IN 1
#define PIO_SW_CAPTURE 0
#define PIO_SW_DATA_WIDTH 18
#define PIO_SW_RESET_VALUE 0
#define PIO_SW_EDGE_TYPE "NONE"
#define PIO_SW_IRQ_TYPE "NONE"
#define PIO_SW_BIT_CLEARING_EDGE_REGISTER 0
#define PIO_SW_FREQ 100000000
#define ALT_MODULE_CLASS_pio_sw altera_avalon_pio
的
#define PIO_SW_BASE 0x094110c0 定義了SOPC Builder為pio_sw所規劃的位址,而system.h也是Nios II EDS根據nios_ii.ptf所產生的。
413行
#define PIO_LEDR_TYPE "altera_avalon_pio"
#define PIO_LEDR_BASE 0x094110a0
#define PIO_LEDR_SPAN 16
#define PIO_LEDR_DO_TEST_BENCH_WIRING 0
#define PIO_LEDR_DRIVEN_SIM_VALUE 0
#define PIO_LEDR_HAS_TRI 0
#define PIO_LEDR_HAS_OUT 1
#define PIO_LEDR_HAS_IN 0
#define PIO_LEDR_CAPTURE 0
#define PIO_LEDR_DATA_WIDTH 18
#define PIO_LEDR_RESET_VALUE 0
#define PIO_LEDR_EDGE_TYPE "NONE"
#define PIO_LEDR_IRQ_TYPE "NONE"
#define PIO_LEDR_BIT_CLEARING_EDGE_REGISTER 0
#define PIO_LEDR_FREQ 100000000
#define ALT_MODULE_CLASS_pio_ledr altera_avalon_pio
#define PIO_LEDR_BASE 0x094110a0 定義了SOPC Builder為pio_ledr所規劃的位址。
設定標準輸出為LCD
執行結果
透過μC/OS-II,一個thread在LCD顯示,另一個thread控制SW與LEDR。
完整程式碼下載
Lab1_files.zip (一個未完成的半成品,可以根著本文一步一步完成)
hello_ucosii.7z (最後完整的結果)
Question
(這是我當時給學生的homework,各位有興趣可以自己自做做看)
1.為什麼只有SDRAM的clock需要phase shift -65度?為什其他的硬體的clk都不需要phase shift?
2.可以使用pointer,而不使用IORD()與IOWR()嗎?解釋你的理由?
#define LEDR (unsigned int *)LEDR_BASE
void task2( void * pdata) {
while ( 1 )
{
* LEDR = * SW;
}
}
3. 試著將Hello World執行在On-Chip Memory,並解釋你所使用的方法。
Conclusion
對一個初學者來說,要讓Nios II能順利的在DE2-70跑起來,需要面臨很陡峭的學習曲線,因為其中有不少小trick很容易忽略而失敗。Nios II就只是這樣嗎?這只是Nios II的起手式,本系列共用4個Lab,此為第1個,第2個Lab以七段顯示器為範例,示範如何寫Slave IP,第3個Lab為Terasic的DE2_70_SD_Card_Audio_Player範例,除了實際體會HW/SW Co-Design外,將學習如何讀取SD卡,第4個Lab將實作一個數位像框,示範如何寫一個Master IP,並可直接從Flash啟動。
See Also
(原創) 如何自己用SOPC Builder建立一個能在DE2-70上跑μC/OS-II的Nios II系統? (SOC) (Quartus II) (SOPC Builder) (Nios II) (μC/OS-II) (DE2-70)
(原創) 如何設計一個七段顯示器Controller? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)
(原創) 如何設計一個SD卡Wav Player? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)
(原創) 如何設計一個數位相框? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)