创建完成工程之后,需要创建顶层实体。创建完顶层设计文件之后,使用SOPC Builder创建NIOS II 嵌入式处理器,添加、配置系统的外设IP,组成Nios II系统模块。 Nios II 系统模块设计完成之后要加入到该顶层实体中,然后进行其他片上逻辑的开发。 X: \4 f7 x/ P/ ^3 }7 s
2.3.1 创建顶层实体+ D" @8 I! l; T, Q9 ?9 Z
(1)新建的工程窗口中,选择FileNew; : v b H- ]8 ?% O$ y
(2)在Device Design File页中,选择Block Diagram/Schematic File,即原理图文件,也可以选择硬件描述语言的文件形式。单击OK。
1 t. B5 D; S6 \ }(3)出现一个模块编辑窗口。
7 n5 {# A; R5 `/ N4 E9 f(4) 选择FileSave As,出现Save As对话框,显示的目录为之前设置的工程目录,文件名为之前设置的顶层实体名(由于这是工程的第一个文件,系统会默认为顶层设计实体的名字)。确定Add to Current Project选项被选中,点击Save文件被保存并被加入到工程中。
. Y0 j3 q+ y/ a# R9 Y" U: E8 x 0 _ q: U- Y8 k0 u5 G( q
2.3.2 创建Nios II系统模块
- C3 z; H# B8 Z! |+ u6 ^ 创建NIOS II系统模块需要使用SOPC Builder,它是Quartus II中的一个工具,使用SOPC Builder可以创建一个Nios II 系统模块,或者创建多主设备SOPC模块。一个完整Nios II的系统模块包括Nios II处理器和相关的系统外设。所以创建系统模块的流程是先创建一个系统,然后添加Nios II CPU和外设IP,然后进行相应的设置,最后生成实例,然后将其加入到工程的顶层实体中去。
0 X3 a& {* \* i4 H5 L一、创建系统
& ~1 e# [3 |' x A启动SOPC Builder,选择ToolsSOPC Builder,出现图2-10的Create New System对话框。键入系统的名字,选择硬件描述语言Verilog或者是VHDL。 7 w% F. {' p$ k8 R
- ^, H" r" b" K: C& O
8 B' w$ |# {$ d% k8 [. i- N
7 Y( f+ n A# |二 、设置系统主频和指定目标FPGA 1 k7 F/ b6 ^ `7 n
在Target栏中的Board部分指定我们这本书使用的核心开发板——Cyclone II (EP2C35)。也可以在Board部分选择Unspecified,然后在Device Family选择Cyclone II。
' r9 R! J9 M* ?2 S1 }3 K用户需要设置系统的时钟频率,该频率用于计算硬件和软件开发中的定时,比如时钟分频或波特率。这里我们设成85MHz,还可以选择是否选用流水线。
* s8 L) t+ T- l; w8 X; |- W三、加入Nios II CPU和 IP模块 8 \* R1 S" X: \3 e$ z. J0 k
首先加入Nios II软核,Nios II 是软核CPU,共有三种类型的CPU可供选择:Nios II/e(经济型)、Nios II/s(标准型)和Nios II/f(快速型)。用户可以根据实际的情况进行选择。Nios II是一个用户可以自行进行定制的CPU,用户可以增加新的外设、新的指令等。
$ X) @% ~3 W8 g4 J1 h0 }, d添加Nios II CPU的步骤如下: , R! i% ` k- g
1. Avalon Components 下面选择Nios II Processor; ; ~; j7 W9 l& w( R0 S5 `% J
2. 点击 Add,出现Nios II CPU的配置向导,共有三种类型的CPU可供选择; S! [, v8 C W/ X' q
根据需要选择相应的一种Nios II核,我们选择标准型的Nios II核,Hardware Multiply选择none,不选择Hardware Divide点击Next,进入Caches & Tightly Coupled Memories设置窗口;
$ v4 @( d% y# |0 O 设置Nios II的Cache和与CPU直接相连的存储器端口(不通过Avalon总线),选择Instruction Cache为4Kbytes,不选中Include tightly coupled instruction master port(s) ,点击Next进入Advanced Features设置页面。
$ h* {0 A0 L! j2 y; M8 R7 E Advanced Features的设置页面是Quartus II 6.1 版本才有的设置,这里不选择Include cpu_resetrequest and cpu_resettaken signals点击Next进入JTAG Debug Module设置。 共有4个调试级别可供选择,这里选择Level1即可,该级别支持软件的断点调试。JTAG调试模块要占用较多的逻辑资源,如果整个系统调试完毕了可以选用No Debugger以减少系统占用资源点击Next进入自定义指令的设置。 2 Z4 D- ]9 C8 B i+ r9 m
因为本例不用到任何的自定义指令,这里不作任何的设置,点击Finish完成CPU模块的添加。
7 a- y% |% ~/ Y" M- @ / L0 w& z( X- N- t: A
除了Nios II CPU,电子钟设计需要添加的IP模块包括:
" J3 ]! u' z2 H; @6 rTimer
2 y0 k8 @- J( d0 ^/ NButton PIO
8 W3 o8 y6 ~* @8 v6 Z% c2 S$ r8 sLCD控制器 4 R* Z4 x' h) |; ?. u1 N
External RAM Bus \; ]# `* m) ~+ j' o
External Flash Bus
! q$ D) p+ n+ ~& E9 BExternal RAM interface
* m. J9 ]2 y- r9 c, h- TExternal Flash Interface
) \0 p" t! ]$ ^) h1. 添加定时器
. F- K8 b( v( U定时器和Nios II CPU一样,用户可以对其进 行定制。添加定时器的步骤如下:
! J" E7 ?! {2 _' Y" `6 M/ f(1)在Avalon components下的other库中选 择Interval Timer并单击Add,Avalon_Timer-timer_0的向导窗口出现;
2 Q9 ?& m! S7 X. y0 F/ w. U9 K" g0 y1 P(2)配置定时器,点击Finish,完成定时器的添加。
" _ n# L4 c' }(3)可以对Timer进行重命名,我们这里取缺省的名字。 % E% w9 O* ]3 X% Q
2. 添加Button PIO
0 A7 F) M: H$ k0 l( `' F; M(1)在 Avalon components下的other下选择PIO,单击Add,出现Avalon PIO-PIO_0的向导; . W, G9 O/ |* u7 o
(2)在Basic Settings页中,设置width=4bits,direction为Input Ports Only;
, O4 ?* S7 ?* h(3)在Input Options页中,在Edge Capture Register下选中Synchronously Capture,然后选择Either Edge;
4 L0 m( m3 D- I1 ` (4)在Interrupt下选中Generate IRQ,然后选择Edge; 9 _ \8 | D6 }- W2 h7 ^/ f
(5)点击Finish,返回到Altera SOPC Builder NIOS2的窗口; + Y% |" |! a: N, L
(6)右键单击Module Name下的pio_0,从菜单选择rename,重命名为button_pio. ' e# r Q& j x$ X) O9 ^
3. 添加LCD控制器 ' i9 f9 b. C Z+ ?9 T
(1)在图2-11的窗口中的左侧的Avalon components下的display库中选择Character LCD(162, Optrex 16027),单击Add;
8 m1 W. S* a: S5 H' p/ b q(2)Module Name下出现,lcd_16027_0; : G$ k5 o( [5 U6 ]7 V
(3)将其重命名lcd_display。
- a, Z; x$ m; V* u4.添加外部RAM接口 , K! F& V, q. L# x
(1)Avalon components下的Memory下面选择Cypress CY7C1380C SSRAM,单击Add,出现SSRAM (Cypress CY7C1380C)-ext_ssram的向导;
) ~/ w/ x) D3 ]' Q3 ]- P1 M9 b(2)在Timing Parameters下面设置Read Latency 为2 clocks,在SSRAM下面设置Memory Size为2Mbytes 4 q8 `0 m. s3 U; {: J/ e# u
(3)单击Finish,返回到Altera SOPC Builder NIOS2的窗口; 2 \* f9 B" I" ]5 [
(4)右键单击Module Name下的ssram_0,从菜单选择rename,重命名为ext-ssram。 7 v( f" o$ c4 I+ R& G% Q4 i
5. 添加外部闪存接口 * k, J: \0 Y' W" W
(1)在Avalon components下的Memory下面选择Flash Memory(Common Flash Interface),单击Add,出现外部闪存接口向导; 7 Z1 X# G( X* L# Y b
(2)在Attributes页中,可以在Presets列表中选择相应的闪存的接口,这些闪存的接口都是经过测试的,如果列表中没有,用户可以自己定义闪存的Size和Data Width;
9 r; l( x8 N+ v7 h9 M- z (3)在timing页中,可以设置闪存的读写时序要求,可以设置Setup, Waite, hold时间等参数,通常保留缺省的设置; % y5 C7 g9 P0 i9 F1 N& E3 I
(4)如应用选择的闪存接口不在列表中,需要自己定义Size和Data Width,和时序要求;
0 N* O3 z4 |& Q8 d3 r(5)点击Finish,返回到Altera SOPC Builder NIOS2的窗口,Module Name出现cfi_flash_0,对其重命名为ext_flash。
& R7 _8 l; L8 I* p" u ' F* k s' L7 `* U) w
6. 添加外部RAM总线和外部flash总线(Avalon三态总线桥)
- [9 w5 O' W, i8 ]" m `5 W为了使Nios II 系统能与开发板上的外部存储器通信,必须在Avalon总线和外部存储器之间加入Avalon三态桥。 ( K" \! D8 p5 m% M2 m- Q7 o
步骤如下: : V- F* N% h0 M# v! h3 p4 J
(1) 在Bridge下,选择Avalon Tri-State Bridge,点击Add,出现Avalon Tri-State Bridge – tri_state_bridge_0向导;
9 l/ }& [: {" E(2) Registered选项默认为选中; * m1 l( H( J- x
(3)单击Finish,返回到Altera SOPC Builder NIOS2的窗口;
2 y) I( \( w4 C* X' x (4) 将其重命名为ext_ssram_bus; 7 Z( O3 V" L3 F( a
(5) 重复前三个步骤,在添加一个Avalon三态总线桥,并重命名为ext_flash_bus.
$ Y& c0 L- [% c U7.添加JTAG UART " @6 ]+ L- @% r6 V. c8 m' \
(1)在Avalon components下的Communication下选择 JTAG UART,点击ADD,出现添加向导。 ; }1 [9 H0 x" J0 L8 p; G8 g, R
(2)按照缺省设置,点击Finish。
7 L# Z. w+ J8 C. }0 g(3) 将其重命名为JTAG_UART. 9 |4 g( _: n# U
8. Nios II系统的连接
+ I* a' |9 K+ x9 X4 G( P2 E 主要是外部RAM接口要和RAM的三态桥连接,外部的Flash接口要和flash的三态桥连接。所有添加的IP连接都是系统自动完成的,除了上面提到的三态桥和外部存储器的接口的连接之外,其它的连接用户不用修改,但对于三态桥和外部存储器接口的连接,系统的自动连接可能和用户的开发板不匹配,用户需要进行手动的更改。针对我们所用的开发板的情况进行的设置,因为本书用到的开发板外部的SRAM和外部的Flash没有使用共用的数据线和地址线,所以必须为它们分别添加一个三态桥。 : W2 B2 Q X" E) r; @
2.3.3分配IP模块的地址和中断号 在以上添加IP的过程中,SOPC Builder为各个IP模块分配了一个默认的基地址,用户可以改变这些默认的分配。如果用户自己分配的地址出现冲突,SOPC Builder会给出警告,用户可以按照下面的步骤来进行分配和解决地址冲突问题。 ; ]; B0 a3 G* o5 d3 Q/ u- b% Y
下面我们给出一种自定义的地址分配实例,将闪存的基地址设定为0x00000000,步骤如下:
M% L4 z& P# b% W- ^" e( h' }(1)单击Flash外设的Base栏,将地址改为0x0,然后回车,这时SOPC Builder的消息框中出现错误的提示信息,这是因为闪存的地址和其它的外设地址发生了冲突。
6 l* [5 F: [* z6 r(2)选择Module菜单中的Lock Base Address操作,一个挂锁的图标出现在闪存基地址的旁边。 # g2 @: R8 O* H% }: ]
(3)选择System菜单中的Auto Assign Base Address操作,来解决外设的地址分配冲突问题,SOPC Builder调整其它外设的地址来避开与闪存地址的冲突,错误提示的消息就会消失了。 / k6 y5 p2 o+ q; {
(4)用户可以手动修改各个外设的中断号,中断号越低,中断优先级越高,用户也可以采用自动分配中断号,选择System菜单中的Auto Assign IRQs,但SOPC Builder不处理软件操作,采用自动分配中断的策略不一定是最优的,用户最好是根据自己的应用来确定外设的中断优先级,采用手动的分配。 5 Q& X4 x5 O% ~0 l; `
2.3.4 配置NIOS II 系统 系统的IP模块添加完成之后,还需要对系统进行配置。点击Nios II More “cpu_0” Settings 页,用户可以进行如下的设置:
' x' U3 ? O; V/ @* G Reset Address:可以选择存放Boot Loader的存储器和设置Boot Loader在存储器中的偏移,我们这里选择ext_flash,偏移选择默认;
' H, A9 I3 E; s/ j( X" j QException Address:可以选择存放异常向量表的存放的存储器和设置异常向量表在存储器中的偏移,我们选择ext_ssram,偏移选择默认;
" g$ |% Y7 e+ R2 M6 L- F( k" {Break Location:如果NIOS II 包含有一个JTAG Debug模块,SOPC Builder会显示这项内容。其Memory Module总是JTAG Debug Module,Offset 固定为0x20, 地址由JTAG debug module基地址决定。用户不能修改Break Location的各个域的内容。
L8 r7 D" A. j; d- H9 {2.3.5 生成NIOS II并加入到工程中 NIOS II系统是工程的一部分,我们首先是生成它,然后加入到工程中去,然后将整个工程下载到FPGA芯片中去。单击System Generation,在Option下进行如下的设置:
- k3 z& Y3 Y9 d2 e- z* C% q选中 HDL,会生成系统模块的硬件语言文件。 # p/ Q @' h! I, u; _# c; \3 [; R
选中 Simulation,如果安装了ModelSim软件,会生成用于仿真的相应的文件。 3 T! y! ]6 B. S9 V- I5 @* B: }
单击 Generate,SOPC Builder会提示生成系统的进程,系统生成完成时会提示”SUCCESS: SYSTEM GENERATION COMPLETED”。单击exit 退出SOPC Builder。
8 Z, k* F, }" p0 f1 S 系统生成完成之后,SOPC Builder为这个定制的NIOS II系统模块创建了一个符号,要把Nios II系统加入到工程中去,遵循如下的步骤:
! k2 G. Z$ e( z. [. N(1)在 Quartus II软件中,打开顶层实体(BDF格式),在BDF窗口中任意处双击,出现 Symbol对话框;
, X% d& ?( Z/ }: e" q# {: w(2)在Symbol对话框中单击Project来展开工程目录,其下出现NIOS2(本例采用的系统名),选中它,右侧出现了系统的符号表示; ! h8 `6 J0 N5 B* r: K
(3)单击OK,Symbol对话框关闭,NIOS2的符号轮廓被附着在鼠标的指针上。
% W5 I6 N3 y9 X( E" W( X) v8 p(4)BDF窗口中任意空白处单击一下,NIOS2的符号出现在BDF窗口中,这样我们创建的系统已经被加入到工程中了。 / Y( C- y: H4 x1 X! V
, V! Z( A9 O0 J9 D% s 2.3.6 加入引脚和嵌入式锁相环 除了NIOS II系统之外,可能还要有其它的硬件逻辑,我们这里加入一个嵌入式锁相环,嵌入式锁相环有两个时钟输出,一个输出SSRAM提供时钟,另一个时钟的输出为NIOS II CPU提供时钟,然后添加输入、输出、双向引脚,以实现和FPGA外部的外设进行通信。 - b, I8 G* ]# E
加入嵌入式锁相环的步骤如下: 1 S1 B2 Z! g* @9 y
(1) 点击ToolsMegaWizard Plug-In Manager,出现MegaWizard Plug-In Manager向导Page1窗口,点击next 在MegaWizard Plug-In Manager Page2 窗口中的IO下面选择ALTPLL,器件选择Cyclone II,输出文件类型选择VHDL,文件名为ssram_pll,选中Return to this page for another create operation,然后点击Next,出现MegaWizard Plug-In Manager-ALTPLL [Page 3of 9];
$ e& c, x a) a- |1 ]) _! F 在MegaWizard Plug-In Manager-ALTPLL [Page 4 of 10]窗口中,不做任何选择,点击next;
3 C- X- u+ J7 p: L; ~在MegaWizard Plug-In Manager-ALTPLL [Page 5 of 10]窗口中,单击next;
$ W, @$ g4 S9 x7 g, i( _- ]; A2 ^ 在MegaWizard Plug-In Manager-ALTPLL [Page 6 of 10]窗口中,设置c0输出时钟,首先选中Use this clock选项,设置时钟频率为85MHz,占空比为50%。点击Next会进入c1输出时钟的设置;
, W; m; Y% U- a9 P 嵌入式PLL可提供3个输出时钟,我们使用其中的两个,MegaWizard Plug-In Manager-ALTPLL [Page 7 of 10]窗口中,在c1时钟的设置页面上,选中Use this clock选项,设置时钟频率为85MHz,点击Next; 5 _& W& e, ]3 _ C7 h- Y9 w
在MegaWizard Plug-In Manager-ALTPLL [Page 8 of 10]窗口中,不选中Use this clock选项,即我们不使用c2时钟,点击Next;
' a% o! E1 N q( ^- P在MegaWizard Plug-In Manager-ALTPLL [Page 9 of 10]窗口中,给出了用于仿真必须要产生的文件,点击Next;
* i2 u9 l9 S" x; N3 T3 N" g! c+ e在MegaWizard Plug-In Manager-ALTPLL [Page 10 of 10]窗口中,给出了用户选择要产生的文件,不做改变,采用默认配置,点击Finish完成PLL的生成。 , S3 a. x& ?: H. B
在顶层实体的bdf窗口中双击鼠标,出现Symbol添加窗口,在project下面选择刚才建立的ssram_pll,点击OK。ssram_pll的轮廓会附着在鼠标上,点击bdf窗口的空白处,将嵌入式锁相环加入到了工程中。 8 e: g) N+ s- u- [1 Q/ b& A
引脚添加的步骤如下:
/ y( \% [3 B0 u* G5 Z3 `0 g(1)在顶层实体的bdf窗口的空白处双击鼠标,出现Symbol添加窗口,在altera/quartus/libraries下面选择primitives,再在其下选择pin,在其中有三种类型的引脚,有bidir,input,output,分别为双向、输入和输出引脚,选择相应类型的引脚,点击OK。
7 `/ f; E; v0 Q' g& s(2)点击bdf窗口的空白处,即将引脚加入到了工程中。
$ r9 M9 u I$ j! g+ ^ ]' y, x(3)重复上面的步骤添加为各个端口添加相应类型的引脚。
: N0 v. [- G: a4 _ 连接引脚和命名引脚 & h. D3 f0 g% j6 i0 a
第一个加入的引脚的名称缺省为pin_name,之后加入的引脚名称依次为pin_name1,pin_name2向上递增,为了便于理解和记忆,需要对引脚重新命名,使其和其传输的信号联系起来。 ! u* ^ W6 k/ |! Q5 l& @' l( N C1 t
命名引脚的方法如下: (1) 双击引脚的“pin_namen”部分,pin_namen的文字变成高亮,可以对其编辑。 " H% p/ j: N v' f6 G
(2) 对其他的引脚重复以上的操作,修改成具有意义的名字。 _4 I( l/ w! ~: z
(3) 对于总线型的引脚,引脚名称之后要标识出总线的位数,如ddr_a[12..0],在引脚名称之后加上方括号,然后写上最高位和最低位,用两个..隔开。
D! C& r9 J' Y$ J4 A(4)将嵌入式锁相环和系统模块等连接起来,并将引脚连接到相应的端口上。
* n. y1 l6 L8 e
, b* }) E/ b3 ]- `, ?0 ^+ X: U
& T7 W- T; |( c6 P! ~4 N5 t6 X! E4 W8 N) x9 p- ^
[ 本帖最后由 kenson 于 2009-1-23 14:17 编辑 ] |