NIOSII设计 DE2实验板.docx
- 文档编号:7777665
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:29
- 大小:1.18MB
NIOSII设计 DE2实验板.docx
《NIOSII设计 DE2实验板.docx》由会员分享,可在线阅读,更多相关《NIOSII设计 DE2实验板.docx(29页珍藏版)》请在冰豆网上搜索。
NIOSII设计DE2实验板
※※※※※中断※※※※※
XX百科上对“中断”的定义:
在计算机执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的时间处理程序。
待处理完毕后又返回原来被中断处继续执行或调度新的进程执行的过程。
翻译成白话:
有客人要来你家做客,你正在洗菜做饭,你怎么知道客人已经到了呢?
有两种办法,一是让客人到了之后按门铃,另一种是你不断地去门口瞧瞧人有没来到。
对应到nios系统中,CPU即“你”,硬件外设即“客人”,硬件有数据更新(“客人”到了),第一种方式称为“硬件中断”(按门铃),第二种方式“轮询”(你在厨房和大门口之间疲于奔命)。
只是作一个比喻而已,没人会傻到痴痴地坐门口等人,但是硬件系统不分傻与不傻,“轮询”也是一种可行的方式,效率低一些罢了。
前面说过,硬件外设将中断请求传到CPU,必须走avalon总线,因此avalon总线得分配一个接口信号负责中断请求的传送,这个信号的名字为irq。
NiosIICPU体系架构支持32个外部硬件中断:
irq0~irq31,中断号越低,优先级越高。
我们来看看一个硬件外设--电平开关,在以前那个工程DE2_SEG7中加入4位pio组件,当电平开关的值发生改变时,发送一个中断信号给CPU,让CPU跳到中断处理函数--将4位电平开关的值输出到数码管显示。
<1>加入PIO组件,位宽为4,即4个电平开关
这是SOPC组件列表,注意划红圈的地方,多了个中断号irq0
<3>Generate"Nios2_system",在QuartusII里分配电平开关引脚SW[0]~SW[3],编译。
接着打开工程目录下的pio.vhd,可以看到pio控制器确实定义有avalon中断信号irq。
<4>下面打开NiosIIIDE,写软件
C语言在哪里?
2008-03-1316:
55
按照Altera的文档,软硬件之间的过渡部分应该是这个样子:
上次没把"C语言标准库"算进去,是想另开一篇文章来说,而且上次写那几行程序确实没用到C标准库里的函数,altera_avalon_seg7_×××是我们自己定义的,不算数。
典型的C标准库函数有:
open()close() printf() read()...等等,在电脑上用C语言写应用程序,就是拿C标准库函数拼拼凑凑而成。
C语言的简单易用性有目共睹,软件设计人员早已习惯了C语言的语法和思维逻辑,nios要将软件设计和硬件设计隔离开,必须迎合软件设计者的习惯,引入C标准库,这样才能使软件开发人员从其它平台的开发转到nios的时候,不会觉得突兀和陌生。
软件开发人员不会去关心底层硬件实现细节,所谓软件,是很虚的东西,逻辑功能的组织和具体落实到硬件毕竟是两回事,因此必须把C标准库中那些很“虚”的函数跟实际的硬件操作对应起来,这个过程称为“移植”。
既然规定nios的软件用C语言实现,altera肯定为用户完成了C标准库的移植,将C标准函数与硬件操作一一对应。
但是,硬件种类千千万万,altera考虑得再怎么周全,也不可能顾得上所有的硬件,于是,它想出一个办法:
把硬件分门别类,把同一类硬件的共性提取出来,形成一个“虚拟设备”,然后确定这个“虚拟设备”适用于C标准库的哪些函数,把这些函数指针放到一个结构体中,OK,它的任务就算完成了。
如果设计人员想把一个硬件外设加入nios系统,如果他希望别人能用C函数访问到该硬件,那么,请他考量一下这个硬件能够归到哪个“虚拟设备”名下,然后对照着这个“虚拟设备”的结构体,自个儿实现结构体中的函数去吧。
说到底,这些C标准函数对应什么样的硬件操作,还得自己去填&……%#*!
nios的“虚拟设备”有6种:
◆字符型设备
hardwareperipheralsthatsendand/orreceivecharactersserially,suchasaUART.
◆文件子系统
provideamechanismforaccessingfilesstoredwithinphysicaldevice(s).
◆DMA设备
peripheralsthatperformbulkdatatransactionsfromadatasourcetoadestination.
◆定时器设备
hardwareperipheralsthatcountclockticksandcangenerateperiodicinterruptrequests.
◆FLASH设备
nonvolatilememorydevicesthatuseaspecialprogrammingprotocoltostoredata.
◆以太网设备
provideaccesstoanEthernetconnectionfortheAltera-providedlightweightIPprotocolstack.
似乎写得有点乱了,举个例子清醒清醒。
以LCD显示屏为例,按照“字符型设备”的定义-串行发送或接收字符的硬件外设,可以确定将LCD显示屏归入“字符型设备”,定义“字符型设备”的头文件为alt_dev.h,定义“LCD显示屏”的头文件为altera_avalon_lcd_16207.h,两者对应关系如下图:
结构体alt_dev_s定义了“字符型设备”的共性:
能被open()close()等一系列C标准函数访问,所以,表示LCD显示屏的结构体alt_LCD_16207_dev里包含“共性”的alt_dev类型的变量dev,还有其它一些“个性”的属性base、alarm等,实例化dev就实现了C标准库函数与硬件操作的一一对应,实际上,这个例子中只完成了write()→alt_lcd_16207_write()的对应,其它函数以空指针NULL代替。
这样,我们就可以在软件中用write()向LCD显示屏输出字符。
~~over~~
硬件&软件
2008-03-1016:
18
本文工程下载:
开发环境:
QuartuesII6.0+sp1 NiosIIEDS6.0
上个例子中,我们使用VHDL语言,根据FPGA管脚与数码管和按键管脚的连接,通过一系列的语句控制管脚电平的高低,从而让FPGA实现数码管显示功能。
可见,对于比较简单的功能实现,可以像这个例子中那样,直接控制最底层资源,甚至对每个管脚在每个时刻的电平输出了如指掌。
但是,如果设计稍显复杂,那么对底层细节的过多关注就会成为一种累赘。
试想我们平时在电脑上编写C程序,比如在显示器上输出一行字,我们只用一句printf()即可完成,至于打印命令怎么传到显示芯片上,哪个芯片管脚怎么变化,又怎么传到显示器上输出,诸如此类涉及底层硬件的问题,我们没必要关注太多。
于是,我们把用printf()这类高级语言描述设计逻辑的工作称为软件设计。
显然,软件只是一种抽象的看不见摸不着的东西,它的结构接近于人类思维逻辑。
无论软件再怎样构思精妙,只有在硬件上才能体现出实际效果。
做计算机开发应用程序的时候,硬件是现成的,软硬件之间的桥梁早就由操作系统给你搭好了,我们只需专心完成软件的构思和设计就OK。
显而易见,软硬件的分工会给电子设计带来极大的方便,自然有人把这种分工方式引进FPGA设计领域,琢磨着怎么在小小的FPGA上也搞个软硬件协同设计,负责硬件设计的和负责软件的各司其职,最后pia一整合,效率倍增。
来看看nios是怎么做的。
拿出DE2开发板,上面很多外设接口和与之连接的芯片,那是硬件,中间有一块大的CycloneII芯片,里面是空的,等着我们编写程序下载到里面运行,前篇文章我们用最原始的方法写了个数码管控制器,这次我们换种方法,同样是数码管控制器,用软硬件协同设计来完成。
跟计算机对比,硬件我们有了,软件就用C语言来写,但是nios系统可没提供WinXP,也就是说软件和硬件之间的那座桥还得自己解决。
看上图,这座桥分为3个层次:
硬件控制层,设备驱动层,硬件抽象层(简称HAL)。
既然是软硬件的过渡部分,那么这3层的设计需要对硬件和软件都有一定程度的了解,姑且称之为“软硬件混杂设计”吧。
每一层所要完成的任务,就是整合和简化硬件操作细节,整合,再整合,使其一目了然。
<1>硬件控制层
与硬件直接打交道的是硬件控制层。
上面提到,搭“桥”的目的是让软件设计人员可以完全忽略硬件操作细节,因此,我们希望所有的硬件细节都能在这层解决,并向设备驱动层提供整齐的“接口”。
之前的例子可看作硬件控制器的雏形,但还缺少与设备驱动层的接口。
何为“整齐”呢?
比如说,设计数码管控制器,我想让它显示数字“5”,最好的方法是,我将数据“5”和表示“显示”的命令从设备驱动层传给硬件控制层,直接告诉它:
我要“数码管”“显示”“5”。
至于要控制哪个管脚电平高低才能显示“5”,全由硬件控制层负责。
类似这样分工合作的例子在日常生活中屡见不鲜。
比如说,邮局要将一封信送给家住A小区的张三,邮递员把信放入A小区的信箱,小区物业再去确认张三的具体住处,把信最终送到张三手中。
类比可见,邮局相当于设备驱动,物业相当于硬件管理器,张三则是具体的硬件,邮局和物业之间的接口是物业提供的信箱,设备驱动和硬件管理层之间的接口,我们称之为“寄存器”,同样由硬件管理层提供,“寄存器”是两层之间得以明确分工和相互联系的关键。
设备驱动开发人员眼中的硬件就是一组寄存器的抽象,通过读写寄存器间接控制硬件行为。
那么,在数码管控制器里加入一个数据寄存器和一个命令寄存器:
data_reg存储待显示的数据,cmd_reg为‘1’时显示,为‘0’时清空。
<2>Avalon总线
你可能会说,这有什么?
在每个硬件管理器和设备驱动之间都建立一个通道呗。
这是最直接的办法,但显然不是最好的办法。
试想,城市为什么要建高速公路呢?
多修几十根羊肠小道不也一样能跑车吗?
有人回答:
为了收养路费呗。
$%@&&!
小路上开车,速度慢且不说,管理协调是个大问题,是一条大公路容易管理,还是几十根羊肠容易理顺?
好了,回到正题,nios系统需要一条“高速公路”,称为“总线”,“总线仲裁器”则行使“交通管理局”的角色,控制数据的进出,并为每个硬件提供一个进出“高速公路”的接口,用“地址”来标识这个接口的位置。
nios采用的是Avalon总线,它有着一套接口规范:
同步时钟clk
片选信号chipselect
地址address
读请求read
读传输readdata
写请求write
写传输writedata
这些是比较重要的接口信号,其它的不一一列举了。
硬件控制器要接入总线,必须遵循接口规范,就像高速公路出口必须摆个收费站一样。
那么在在数码管控制器里加入Avalon总线信号:
既然加入了两个寄存器和avalon信号,就需要对硬件逻辑进行必要改动,大致过程是,当chipselect和write有效时,将write_data赋给address对应的寄存器;当chipselect和write有效时,将address对应寄存器的值赋给read_data。
另外,根据这两个寄存器的内容决定数码管输出信号oSEG0。
代码不贴出来了,具体见工程压缩包。
<3>设备驱动程序
其实,“总线仲裁器”也可看作一种硬件控制器,只不过它管的不是具体的硬件,而是负责数据的传输。
那么它也有自己的设备驱动,封装了总线操作的细节。
既然总线是现成的,我们秉承“拿来主义”的原则,甭管它怎么实现的,会用就行。
例如,数码管设备驱动要把数据“5”和“显示”命令传给数码管控制器,设计两个函数,由于数据和命令的传递必须经过总线,那么需调用总线驱动函数IOWR(基地址,偏移量,数据),另外,读取寄存器用到IORD(基地址,偏移量),这两个函数在
至此,“桥”搭完。
函数功能从字面上很好理解。
刚才定义两个寄存器时,data_reg在前面,所以偏移量是0,cmd_reg在后面,偏移量是1。
××_REG_MSK称为掩码,avalon总线数据接口共32位,但我们设计的data_reg位宽是3,cmd_reg位宽为1,掩码的作用在于告知寄存器宽度,知道就行,实际上用不着。
××_REG_OFST是寄存器内的偏移量,这里同样用不着,先写上吧。
OK,我们的数码管设备驱动文件正式出炉了,看看是不是简洁明了很多啊?
<4>硬件抽象层(HAL)
设备驱动程序封装的仅仅是对某个寄存器的一次读写操作,功能单一,需要在硬件抽象层再做一次封装。
直接将这些函数列出来,一目了然,不作多余的解释了。
至此,“桥”搭完。
接下来在把我们的“数码管控制器”加入sopcbuilder系统中。
现在几乎所有讲nios的书都会提及自定义用户外设,而且用的都是altera官方提供的例子PWM,本文的“数码管控制器”就是照着它依葫芦画瓢改过来的,呵呵,惭愧惭愧,之所以想改它,一是因为它用的是verilog而不是VHDL,而大多数人先接触却是VHDL;二来PWM的显示效果似乎不太明显,改成数码管显示相对比较有成就感;第三,PWM的逻辑稍微有一点点复杂,我们的重点在于说明怎样自定义外设,当然例子越简单越好。
既然是照着PWM原样改的,所以本文工程的结构与之保持高度一致,将其加入sopcbuilder的步骤也差不多,这里我就不再码字了,各位照着书上做吧:
《SOPC嵌入式系统基础教程(周立功等著)》第8章……
再接下来,建立一个包含“数码管控制器”的nios系统,并编写应用程序,实现从0到9计数。
贴张官方的nios设计流程图,看起来很漂亮是吧,不愧是altera的东西,大而全而不乱。
先说最中间的"SOPCBuilder",它的任务是建立一个“以NiosCPU为核心,以Avalon总线为纽带,将各种硬件设备连接起来”的nios系统;这个系统要在FPGA中运行,所以必须挂靠一个QuartusII工程,用左边的QuartusII进行分配引脚等等工作,生成硬件系统;接着,右边的NiosIIIDE就可以在这个硬件系统上设计应用程序了;最后将硬件系统和软件程序分别下载到FPGA芯片上,大功告成。
下面stepbystep
<1>QuartusII新建一个工程名,工程名"DE2_SEG7"。
<2>"Tool"→"SOPCBuilder"打开SOPCBuilder。
<3>"SystemName":
nios2_system 选VHDL。
一个包含“数码管控制器”的最小系统至少由3部分组成:
CPU必不可少,RAM存储代码,还有刚才设计的"seg7_avalon"。
<4>加入"NiosIIProcessor",选"NiosII/e",精简型够用了。
<5>加入"On-ChipMemory",类型选"RAM",位宽默认"32bits","TotalMemory"选"48Kbytes",等会儿软件要占用四十多K空间。
<6>加入"seg7_avalon"。
<7>将这三个组件的名称改好看点,然后设定RAM的基地址为"0x00000000",再右键锁定基地址,如图:
为什么要锁定RAM的基地址为0呢?
点选第二个选项卡,可以看到"ResetAddress"对应着RAM,系统的复位肯定要从地址0开始。
<8>由于刚才人为改动了地址分配,弄乱了,让系统自动再分配一次,当然被锁定的RAM基地址是不会变的。
"System"→"Auto-AssignBaseAddresses"。
最终系统组件列表如下:
注意,seg7的地址范围是"0x00010800"→"0x00010807",占8个地址,nios系统的地址按字节分配,也就是说,每个字节占用一个地址,数码管控制器中定义了两个寄存器,avalon总线规定每个寄存器占32位(实际上是不是32位它就不管了,反正按最大32位分配),这样两个寄存器共占去8个字节,自然需要8个地址。
<9>点击"Generate"生成nios系统,回到QuartusII。
<10>新建一个顶层文件"File"→"New"→"BlockDiagram/SchematicFile",引入niosII系统,增加输入输出引脚。
然后,"Assignment"→"ImportAssignment",添加引脚分配文件(在DE2光盘目录下的\DE2_tutorials\design_files\DE2_pin_assignments.csv),改动顶层文件的引脚名称使其与.csv文件中保持一致。
<11>编译,查看编译报告,可见,48K的RAM占用了芯片83%的memorybits,差不多耗光了。
<12>硬件部分已经搞定,关掉QuartusII,打开NiosIIIDE,切换到工作目录下。
<13>"File"→"New"→"C/C++Application","SOPCBuilderSystem"选择"nios2_system.ptf"(就是刚才GenerateNiosII系统生成的东东),再选模板"HelloWorld"(纯属偷懒
),顶上的"name"改成"seg_example","Finish"。
<14>改动hello_world.c,代码的功能为:
先初始化数码管,等待2秒钟,再进行0-9的循环,循环过程中穿插2秒钟的清屏。
SEG7_BASE的宏定义在system.h中,实际上就是在SOPCBuilder中的seg7_avalon的基地址0x00010800。
<15>"Project"→"BuildProject",得到编译报告,软件占用了7K空间……
<16>下载到DE2板上,运行,数码管不停地闪啊闪。
OK,从硬件到软件的一条龙讲完了。
类别:
默认分类|评论(5)|浏览()
什么是nios
2007-12-1823:
47
要弄清楚Nios的概念,追本溯源,牵涉到很多专业名词:
SOPC,SOC,IPCore……等等,对于某些概念,我也是一知半解,如果写错了,请指正,谢谢。
--System
System,也就是"系统"。
什么才能称作"系统"呢?
下图是我们每天都要接触的计算机系统的结构图,很典型的一种系统。
可见,一个完整的系统,至少由CPU、总线、外设控制器等几部分组成。
CPU负责中断分配、地址管理、内存调度等总的控制任务;外设控制器负责与外部设备连接,控制外设的行为;CPU和各个外设控制器之间通过总线交互信息。
嵌入式系统是从计算机系统发展而来的,理应遵循相同系统架构:
拥有一个总的调控中心,使用总线实现系统的可扩展性,新的外设控制器通过总线接入系统。
下图是Nios系统的典型结构图:
Nios系统采用NiosCPU和Avalon总线,外设控制器以独立模块的形式加入系统,这些独立的模块称为"IPCore",全称"IntelligencePropertyCore"(知识产权核),顾名思义,就是开发者拥有其知识产权,购买者拥有其使用权的"逻辑功能块"。
这样看来,上篇文章所做的东西算不算一个系统呢?
当然不算,充其量只是个数码管控制器。
以后的文章会介绍怎样将它改为能接入Avalon总线的"外设控制器"。
下图列举出各个专业名词之间的关系,在一定程度上反映出它们的来龙去脉。
下面一一介绍。
--集成电路(IC,IntegratedCircuit)
在上个世纪50年代之前,三极管的结构一般是一个空心金属管,通过加热管内的灯丝发射电子,称为电子管,功耗相当大。
后来,人们发现可以用半导体材料来制作三极管一类的电子元器件,晶体管的出现,成为微电子技术发展中第一个里程碑,它使得电子元器件与线路能够集成在小小的半导体基片上,为电子设备微型化提供了新途径。
电路板上那些有很多引脚的小黑块就是集成电路,它里面并不复杂,无非是在一片半导体芯片上(一般是硅片)制造出许多三极管,并按照电路的要求把它们连接起来,形成一定功能的器件,这种制造工艺叫"集成",产品就是集成电路。
这里有一篇关于集成电路设计的很有趣的帖子,推荐一下:
集成电路按照应用对象的不同,分为通用集成电路和专用集成电路两大类。
最直观的理解:
通用集成电路是零件,是从各种各样的应用当中提取出来的公共部分,反过来可以被各种各样的应用系统直接添加进去完成基本的功能的部分,比如说各种74系列数字门电路,A/D、D/A转换器,电源电路等等,用一堆通用集成电路组成起来的应用系统,本质上是分立的。
分立的系统最大的缺点是不可靠,同时会存在许多不确定的因素,使得我们在调试和排错的时候遇到很大的麻烦。
与之相对应,专用集成电路(ASIC,ApplicationSpecificIntegratedCircuit)是直接按功能和要求设计出整个系统,并把这个系统做到集成电路上。
这样,系统的本质是集成的,不可靠性和不确定因素要小得多,在性能上要明显好于分立的系统。
--CPU
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NIOSII设计 DE2实验板 NIOSII 设计 DE2 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)