tag 标签: risc

相关帖子
相关博文
  • 热度 12
    2018-5-21 13:10
    6382 次阅读|
    7 个评论
    RISC-V 到底是什么?其实他并不是开源的 CPU 设计方案 大家可能都觉得 RISC-V 是个开源的精简指令集 CPU 设计方案,其实这是错误的。 RISC-V 仅仅是一套精简指令集的定义,开源的意思是任何人都可以免费获得指令集,并且自己去实现指令集,不需要支付任何费用。打个不专业的比方,指令集可以看成一张大楼效果图,图上有大楼漂亮的外观,完整的功能划分,超前的设计理念等等。你可以免费的从网上下载这张效果图,然后找人把效果图造成大楼,租售出去。出效果图的人保证不会来向你收钱。我也有更专业的比方,我把 x86 的指令集免费送给你,你可以自己实现兼容这套指令集的 CPU ,如果你的 CPU 做的足够好,你还可以在这个 CPU 上支持 Windows 。是不是很爽?但爽也是有代价的,我们接着说。 RISC-V 真的免费吗?免费,但成本着实不低 免费,必须免费。指令集在网站上可以直接下载,文档清晰,解释清楚,扩展灵活,一看就是高手高手高高手的作品。由于没有兼容性的累赘,又是最新的设计,肯定非常贴合目前业界对 CPU 指令集的需求,可以说是众望所归。但是问题这个高手只给了一页 A4 纸的指令集, CPU 怎么实现他没告诉你,高手没有提供 HLS 或 RTL 源代码,没有告诉你应该怎么 Layout 。这一切需要你自己想办法解决。就好像给你一张大楼效果图,免费使用。但是想要把这栋大楼造出来,你必须解决一个最重要的问题“ 没有施工图纸 ”。你必须要有一大堆工程师去设计结构,材料,水电管道,电梯楼梯,智能楼宇系统,监控系统。。。。。。,还要有工程队,还要有物业团队。。。。。。所以想把他造出来实在是太困难了。至少需要上市公司的实力,不然可能就只能造个外观接近效果图的小屋子给自己挡挡风了。反正我是用不起这免费的效果图。 为什么不少人喜欢 RISC-V ?喜欢的不一定是合适的。 为什么喜欢?我觉得有以下几个原因: 1. 指令集设计太高超了,精简而高效,既严谨又可以灵活扩展,又有众多业界领袖参与设计。什么 x86, Arm, PowerPC, MIPS 统统都是为了兼容以前的产品拖累了产品创新。就如同贝聿铭团队推出了一份大楼的效果图,各大地产商巨头都说我以后都准备盖这样的大楼,这个楼实在太漂亮了,功能太强大了,设计太先进了,造出来了肯定火,现有的大楼以后都会住着不舒服。 2. 指令集架构开源免费,谁都可以设计兼容的芯片。大楼效果图不要钱,拿来就可以拉几个兄弟开始造, 还可以用效果图找大款亲戚入伙。谁让这图人见人爱呢? 3. RISC-V 还有很好的扩展性,可以根据需求,增加扩展的指令集实现客户化的功能。就好像在大楼上还可以定制一些密室,满足一下自己的小小愿望。 4. 指令集的实现方法自主可控,源代码都是自己写的,可不是放心么。就好像自己造的楼肯定安全,每块砖都是自己选的,物业保安也都是自己雇的,放心 5. 指令集架构的生态链正在成长和完善, toolchain , IDE ,仿真,虚拟机一个不会少。就好像以后可能全国到处都有这样的楼,物业,水电,管理都一套规范。如果要搬到其他城市,家具都不用换,拎包入住。 恋爱容易结婚难,合不合适只有用的人才知道。我来分析一下大家就明白了。 1. 指令集架构好也要有好的设计才能体现出来,涉及 RTL 编码, layout ,半导体制程,封装等一系列技术,这是一个系统工程。 Intel 和 AMD 的 CPU 指令集基本一样,但性能功耗的差异地球人都知道。还有 TI , Cyrix ,这些 PC CPU 先烈们也是用了同样的指令集。采用 Arm 指令集架构的产品就更多了,做的好的也不少,但你能说出名字的可能也就那么几家。所以指令集架构先进不代表 CPU 一定就好,设计水平,工艺,测试标准,等等一样都不能差。就像大楼效果图确实漂亮,但真能造出来的估计不会太多,毕竟自备设计团队,施工队和物业公司的大款太少。而且施工难度着实不小,造出来有没有质量问题还真难说。 2. 指令集架构开源免费,但 HLS 或 RTL 不一定。业界已经有很多免费开源的实现代码了,但没有人会为质量负责,没有三包。解决方法有:买商用的版本, SiFive, Andes 等,但要服务费。也可以自己做,工程师成本自己扛。我感觉都不便宜,出来的东西能不能用现在也不好说,风险不是一般的大。回到大楼效果图的比方,效果图是不要钱,但想要住着个楼。要么买现成的造好的,要么自己设计施工图,材料也要自己买,水电煤还要自己接,造出来有质量问题也要自己负责。都是时间和钱啊。 3. 扩展性好确实很重要,但扩展的指令集就和 RISC-V 关系不大了,虽然组织制定了一系列规范来保证兼容性,但效果怎么样确实不好说。就像效果图上留了一片空白方框,给你做密室,还试图规定密室的布局,但毕竟密室都是自己做的,而且一定是秘密的,一切还是要自己从头来做,感觉没占到免费效果图的光啊。 4. 指令集架构的生态系统的成长是个很复杂和漫长的过程, 5 年 -10 年都很正常。还需要一个领头羊,就像 x86 有了 windows , x86 才真正建立起生态系统,然后是 Linux ; Arm 有谷歌 Android 才能造就现在的成功。同时碎片化也是一个很难处理的问题,特别是对开源的架构,这个问题会更挑战。就像效果图大楼的住户搬到其他城市同样效果图的大楼住,发现楼看上去是一样,但房门比原来的楼小了点,家具搬不进去,密室是有,但里面没有床和卫生间,不好用啊。 基于 RISC-V 的芯片会是个什么样子?什么样子的应该都会有 开源项目参与的人多,当然会丰富多彩,百家争鸣。所以 RISC-V 的芯片肯定会有很多形态。当然也就会有良莠不齐的问题。水平高的团队的产品肯定会好一些,但也不能阻止不太懂的人不尝试吧。所以会有 Intel 的成功典范,也会有 Cyrix 这样的先烈;会有 ARM 在智能手机产业的成功,也会有 MIPS 的逐渐的没落。还有一个特点就是 RISC-V 的芯片应该 SoC 为多,所以 CPU 主频,外围接口,功能模块会比 PC CPU 这样的通用 CPU 要丰富的多。林子大了,肯定什么鸟都会有,我觉得用淘宝买家秀和卖家秀来比喻最贴切,你不能说货不对版,但差距咋就这么大呢?说好的瓜子脸咋就变成南瓜子了,说好的大长腿咋就罗圈了呢?这都是因为虽然基本指令集都一样,但设计的方法和思路各不相同,扩展指令集千差万别。做个不恰当的比喻,虽然衣服一样,但身材不一样,脸不一样,搭配的首饰和配饰也不一样,所以出来的效果可以完全不一样。 RISC-V 到底有没有前途?现在说不准。 可以说有,也可以说没有,说有前途是觉得免费又好用的东西肯定能成功,但还需要考虑更多的因素。原因如下: 1. 大厂可能真的能把好的架构变成成功的产品。就像 Intel 做 x86 CPU, 高通做的 Arm 指令集智能手机芯片。回到效果图的比喻,万科和万达有能力把大楼效果图变成高科技大楼,租金很高,大家抢着租。这个肯定可以有,谁让人家牛 B 呢? 2. 但并不是每个公司都可以免费的从 RISC-V 指令集架构受益,因为他对技术水平,资金投入和时间的要求都不低。可以从第三方买,但一份价钱一份货。我没法自己盖楼,但我从大厂那租或买。但感觉这跟效果图免不免费已经没关系了 3. RISC-V 目前还处于早期的阶段,没有太多的实现和验证,先行者肯定要承担更多的验证,测试等小白老鼠的工作。这是必然的过程,中间的不可控因素就会很多,所以你会发现大公司都加入了组织,但并没有大动作,都是在试水的阶段。就像有公司把施工图纸做出来了,你可以去买,然后找施工队按施工图纸施工,但造出来的房子能不能通过检测人家不保证,因为还没人真把这房子造出来多,到底好不好还不确定。所以谁都会谨慎对待这件事 4. 正因为成熟的过程会比较漫长,所以不确定因素会很多,最后有没有赢家不一定,是大家共赢还是一两家独大也不好说,赢家是因为指令集架构的成功而成功,还是因为其他原因而成功都不好说。是否能达到 RISC-V 设计者的初衷,真的还说不准。但是钻石总会发光的,现在 RISC-V 这颗原石能不能被打造成海洋之星这颗宝石,请大家拭目以待。
  • 热度 24
    2015-3-24 13:33
    1042 次阅读|
    0 个评论
      使用嵌入式微处理器的FPGA设计不断增长。根据Dataquest的统计,一年大约启动10万个FPGA设计项目,其中约30%包含某种形式的微处理器。   形成这种趋势有几个方面的原因。首先,数据流应用更适合可编程硬件,同时嵌入式微处理器更适合于执行控制流的应用。第二,要改变设计时,嵌入式处理器呈现更大的灵活性。最后,用软核的嵌入式微处理器消除了处理器过时的风险。从传统上而言,对嵌入式FPGA微处理器有一些限制,包括成本,速度和设计性能。随着工艺技术和设计技术的进步,这些限制正在不断改善,现在设计人员更有可能在他们的应用中考虑使用嵌入式FPGA微处理器。   与过去相比,现成的微处理器已经大大比嵌入式微处理器便宜。但是,今天的低成本FPGA被证明是一个节约成本的解决方案。如果设计中已经使用了FPGA,处理器可以整合到现有的FPGA架构,节省了分立器件或新的FPGA成本。设计周期也是一个重要的因素。将硬件与微处理器子系统构成相关的架构并进行实施能有多快?编写,测试和在微处理器上调试运行的代码需要多久?在过去几年中,在整体功能和易用性方面,针对嵌入式微处理器开发的软件工具也有了明显的改善。因此,现在可以在几分钟内运行设计,并且进行测试。产品上市的时间缩短了,因为现在用软件实现功能比硬件更快,更简单。   用现成的微处理器达到的性能有良好的历史记录。随着技术的改进,FPGA在功能和整个系统的速度方面有了显著的进步。由于现在的FPGA能够处理更大的带宽,嵌入式处理器对于许多设计有很大的吸引力。此外,由于FPGA与其他专用模块的紧密配合,软IP核的扩展性提供了一个系统接口,就性能和吞吐量方面而言,现在一个片上处理器可以提供卓越的设计方案。   当评估诸如LatticeMico32这样的特殊处理器时,使用嵌入式软处理器的优点非常清楚。    一个典型的嵌入式处理器子系统   让我们来看看一个典型的嵌入式处理器子系统,例如,LatticeMico32软处理器。该处理器需要有能与外界通信的功能,因此通常核连接到一个片上总线系统,在此情况下是WISHBONE开放源代码总线。然后还需要一个存储系统,用来保存处理器程序代码以及处理器核使用的数据。对外部通信而言,在一个典型的系统中有各种接口,从简单的通信接口和连接、更复杂的协议到应用中的专用硬件模块。现在该处理器总线架构需要连接外设和存储器系统。一个典型的系统如图1所示。    图1 典型的嵌入式RISC处理器子系统   让我们来看看处理器核本身:LatticeMico32是基于哈佛总线结构的RISC架构的微处理器(图2)。 RISC体系结构提供了一个简单的指令集和更快的性能。哈佛总线架构提供独立的指令和数据总线,能够执行单周期指令。该处理器拥有32个通用寄存器,可处理多达32个外部的中断。定制的处理器可以插入乘法器或桶形移位器,以及不同的调试功能。 图2 LatticeMico32:一个可配置的RISC处理器核   Mico32可以用于各种存储系统,同时使用内嵌存储器用于存储指令和数据。内嵌存储器可以建立一个本地哈佛结构,并允许单周期访问指令和数据。对于更大的存储器需求,处理器通过一个仲裁器连接到其他的存储器模块或接口。这可以是用FPGA的存储器资源来实现的 “片上”存储器,或接口至外部存储器,诸如SSRAM、Flash和DRAM。处理所有访问协议至外部存储器的合适接口模块是由MSB提供的。提供可选的指令和数据高速缓存,能够配置成各种选择(高速缓存的大小,高速缓存块的大小等等)。   通过一个开放源码Wishbone总线接口,该处理器连接到各种外围元件。针对快速周转周期,图形用户界面可以轻松和快速地创建处理器平台。除了标准存储器控制器,这可能包括各种接口,不仅支持I2C、通用IO、定时器,UART以及SPI,还能支持更复杂的模块,如PCI接口或TriSpeed以太网MAC。   直接存储器访问(DMA)控制器是可用的,添加主器件(master)至Wishbone总线,以免除处理器的数据传输工作。这也允许有DMA功能的外设高效地直接传输数据到存储系统,从而节省了片上总线的带宽。   除了外围元件和DMA,用户可以自定义仲裁方案。总线结构产生器支持主器件(master)方和从器件(Slave)方的总线仲裁。如果能够满足系统性能的要求,主器件方总线仲裁提供了一个简单的低成本解决方案。然而,如果在设计中有多个总线主器件和多个从器件,在任何时间主器件方总线仲裁限制与单总线主器件通信。在许多设计中,通过两个或两个以上的总线主器件同时与独立的从器件进行通信,从器件方仲裁改进了性能。图3展示了可用的仲裁方案。  点击看原图 图3 仲裁方案   用户还可以创建自己的基于Wishbone总线的外设元件,然后通过整合到MSB自动连接到总线。因此,LatticeMico32的架构提供了两种可能性:第一,人们可以创建定制的元件,将它放人MSB中的可用元件列表(图4)。第二,可以构建出所谓的Passthru元件,可以将Wishbone接口引出到核的外面,因此,用户可以在FPGA的其他部分添加任何逻辑块。    图4 创建定制的外围组件   这些配置选项能够针对不同的应用定制LatticeMico32。带宽范围从小的和片内或片外存储器面积优化的控制器到具有多个接口的全功能平台,以及访问更大的存储器(可能是片外)。从FPGA访问其他的逻辑模块还允许处理器系统和FPGA专用模块之间的密切互动,以便进一步改进性能。取消了传统上使用并行于FPGA的外部控制器的复杂访问机制。        可扩展性   由于处理器代码是可读的Verilog RTL代码,用户可以轻松识别IP功能块,诸如取指令单元,指令译码或ALU,以及各种流水线阶段。因此,通过定制指令,这些也可以修改和增强。用户也可以执行操作码。因此,在指令字中,LatticeMico32提供了备用的操作码域。   遵照以下一些基本的步骤,可以构建自定义指令:   增强的指令译码器。这是一个简单的情况,提取内部操作码的功能,并生成需要整合此命令至LatticeMico32的所有必须的控制信号。   写功能的实现并将其整合至LatticeMico32 的ALU。   对于多周期命令,构建必要的拖延信号,以便妥善处理处理器流水线。   如果需要其他的专门逻辑(例如额外的专用寄存器),这可以单独的添加到核。   通过定制指令和添加定制外设,扩展处理器核是一个非常有效的方式,用来定制处理器的核以便实现系统的性能要求。通常情况下,一些专门的功能用硬件实现比软件更好。或并行处理可以获得额外的性能。这种机制能够无缝集成硬件加速模块至处理器架构。这将保持用同样的方式处理这些部件的功能,如同正常的软件代码或使用标准外设。   对于需要数据/信号处理功能的应用,往往需要组合RISC处理器的功能和DSP,以达到系统的性能和吞吐量。添加扩展和定制元件还可以包括信号处理单元。可以用硬件非常有效地实现,使用专用的DSP块,诸如乘/累加,用各种FPGA的硬件都可以实现这些功能。    设计环境   LatticeMico32系统拥有三个集成工具:   MicoSystem Builder(MSB)   针对硬件实现,MSB产生平台描述和相关的硬件描述语言(HDL)代码。设计人员可以选择连接到微处理器的外围组件,以及指定它们之间的连接。   C/C++软件工程环境(SPE)   C/C++ SPE调用编译器,汇编器和连接器,使代码的开发针对运行于用MSB构建的平台。可以通过C/C++ SPE来完成,用MSB构建的平台可以作为参考。    调试器和Reveal逻辑分析器   在C/C + +源代码调试器提供汇编中的调试功能,并能够观察处理器的寄存器和存储器。设计人员还可以使用莱迪思的Reveal逻辑分析器观察和控制硬件中代码的执行情况。   所有的工具和IP已完全纳入莱迪思的ispLEVER FPGA软件设计环境,这使得通过整个FPGA设计流程快速的进行设计。这些工具也有利于有效地使用FPGA的资源。   在构建过程中,用完全可读的RTL Verilog源代码创建处理器的代码及其外围设备。提供用于综合和仿真的脚本,约束文件关注硬件的设置和引脚。   目前有3种操作系统: Theobroma Systems的uClinux 和U-Boot、Micriμm的μC/OS-II RTOS和TOPPERS/JSP的μITRON RTOS。   LatticeMico32提供了一个开放源码许可证。莱迪思的开放IP核许可协议将与MSB工具生成的HDL代码一起使用。大部分图形用户界面将在Eclipse的授权许可下使用,同时对软件的内部运作,如编译器、汇编器,连接器和调试器,许可协议将遵循GNU-GPL。   因为这是开放源码软IP,这个处理器的IP核还可以免费迁移到其他技术并加以实现。    性能和资源利用   LatticeMico32提供高性能和尽可能高的资源利用率。对于关心资源的设计人员,基本配置不使用任何指令或数据高速缓存,单周期移位器,也没有乘法器。对于那些更关注性能的设计人员,全配置使用8KB的指令高速缓存,8K字节的数据高速缓存,3个周期的移位器和一个乘法器。对于需要采用折衷方法的用户,标准配置类似于完整的配置,但没有8K字节的高速数据缓存。表1展示了针对LatticeECP3 FPGA的资源利用率和性能。 表1 LatticeMico32资源利用率和使用LatticeECP3的性能    总结   LatticeMico32是一个完整的嵌入式微处理器设计方案。它提供了一个灵活的架构,并允许用户定制处理器系统以满足系统的要求(性能、成本、功耗)。处理器的IP和专用硬件的密切配合提供了一个易于使用的环境,这也可显著提升系统的性能,使设计拥有很大的灵活性。   LatticeMico32开发工具可以很容易地在FPGA中实现一个微处理器和与之连接的外围元件。易用性确保最少的设计时间,从而使得产品能够更快的上市。    根据开放源代码许可证和软件开发工具各自的开放源代码许可证,如Eclipse和GNU - GPL,提供生成的HDL,莱迪思可以让用户完全控制其设计。开放源代码为设计人员提供所需要的可视性,灵活性和便携性。 
  • 热度 19
    2014-3-12 18:44
    1147 次阅读|
    0 个评论
    在NiosⅡ系统的构建过程中,SoPCBuilder开发环境集成了许多常用类型的设备模型,供开发者调用。在日新月异的嵌入式系统设计中开发环境所集成的接口设备是非常有限的,有时无法满足开发者的需要,SoPCBuilder开发工具允许用户依据规则扩展自己的所需设备,完成系统的设计和开发,开发者按照Avalon总线规范将设备驱动程序集成到SoPCBuilder的硬件抽象层(HAL)中,在SoPCBuilder环境下加载使用,方便了用户开发一个自定制的片上系统。本文通过在NiosⅡ嵌入式系统内部集成了基于Avalon总线的脉冲宽度调制(PWM)从外设,介绍了自定制Avalon设备的过程。将其应用在嵌入式智能小车监控系统,为采用NiosII处理器的开发者提供了一些方法和建议。 1定制基于Avalon总线的用户外设介绍 NiosⅡ的Avalon总线不同于其他微处理器的固定外设,NiosⅡ的外设是可以任意定制的,这使得用户可以根据具体的应用需求而定制。所有的NiosⅡ系统外设都是通过Avalon总线与NiosⅡ软核相连,从而进行数据交换。因此对于用户定义的外设必须遵从该总线协议才可与NiosⅡ之间建立联系。 Avalon信号接口定义了一组信号类型片选、读使能、写使能、地址、数据等,用于描述主从外设上基于地址的读写接口。外设使用准确的信号与其内核逻辑进行接口,并删除会增加不必要开销的信号。 在NiosⅡ系统中一个自定义设备由如下几部分组成: (1)硬件文件:用HDL语言编写的描述自定义设备元件逻辑的硬件描述文件。 (2)软件文件:用C语言编写的设备寄存器文件以及设备的驱动程序文件。 (3)设备描述文件(Ptf):本文件描述了设备的结构,包含SoPCBuilder配置以及将其集成到系统中时所需要的信息。本文件由SoPCBuilder根据硬件文件以及软件文件自动生成。 2基于NiosⅡ系统的PWM设计 PWM是利用数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用于从测量、通信到功率控制与变换的许多领域中。实际上PWM是一种对模拟信号电平进行数字编码的方法,通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电或者完全有,或者完全无。电压或电流源是以一种通或断的重复脉冲序列被加到模拟负载上。通即是直流供电被加到负载上,断即是供电被断开。只要带宽足够,任何模拟值都可以使用PWM进行编码。 2.1硬件设计 硬件文件指的是HDL文件,由以下几个模块组成: 逻辑模块:描述设备的逻辑功能; 寄存器映射模块:为内部逻辑模块和Avalon总线提供了通信接口; Avalon总线接口模块:使Avalon总线访问寄存器从而完成相应的逻辑功能。 2.1.1逻辑结构 对于自定义的PWM也是由以上几部分模块组成。PWM按照以下要求设计: (1)任务逻辑按一个简单时钟进行同步操作。 (2)任务逻辑使用32位计数器为PWM提供一个一定范围的周期和占空比,最大周期可设为232个clk。 (3)可以使用微控制器来设置PWM的周期和占空比的值,因此要提供一个可对寄存器进行读写的接口和控制逻辑。 (4)定义寄存器来存储PWM周期和占空比的值。 (5)微控制器可以通过控制寄存器的禁止位关闭PWM输出。 PWM任务逻辑的结构图如图1所示。 PWM任务逻辑由输入时钟(clock)、输出信号端口(pwm_out)、使能位、32位计数器以及一个32位比较电路组成。clk作为32位计数器的时钟信号,32路比较电路比较32位计数器的当前值与占空比设定寄存器(DutyCycleValueRegister)中的值来决定pwm_out的输出为高或低。当当前计数器中的值小于或等于占空比寄存器中的值时,pwm_out输出低电平,否则输出高电平。PWM周期设定寄存器(Modulo_nValueRegister)用来设置pwm_out的信号周期,当当前计数器的值等于周期设定寄存器中的设定时,产生一个复位信号来清除计数器中的值。使能控制寄存器(EnableControlRegister)能使时钟信号有效或无效,即控制计数器是否计数,从而保持pwm_out输出保持当前不变。 PWM内部包括使能控制寄存器(EnableControlRegister)、周期设定寄存器(Modulo_nValueRegister)以及占空比设定寄存器(DutyCycleValueRegister),如图1所示。设计中将各寄存器映射成Avalon从端口地址空间内一个单独的偏移地址。每个寄存器都能进行读/写访问,软件可以读回寄存器中的当前值。表1是PWM寄存器以及偏移地址列表。 PWM的Avalon接口需要一个简单的从端口,该端口使用Avalon总线信号完成寄存器的读/写传输。PWM与Avalon总线接口所需的信号如表2所示。 2.1.2硬件设计文件与仿真 PWM硬件设计文件包含表3所示的三个Verilog编写的HDL文件。 pwm_tasK_logic.v完成PWM的逻辑功能,图2是此文件在QuartusⅡ环境下的仿真波形。 图2中:clock_divide信号设定PWM输出周期的时钟数,dutv_cycle信号设定一个周期内PWM输出低电平的时钟个数,两个信号设定值决定PWM信号的占空比和周期。 2.2软件设计 如果要使Nios软核能够访问自定义的设备,就必须根据先前的硬件设计按照硬件提取层的文件结构编写设备驱动程序。以PWM为例说明HAL的文件结构,如表4所示。 2.3将PWM设计封装为SoPCBuilder元件 当硬件文件和软件文件都已建立好后,便可以通过SoPCBuilder中带有的设备编辑器将自定义设备封装到开发环境内部,在构建NiosⅡ系统时可以对其直接调用。在SoPCBuilder中单击CreatNewComponent,创建新元件向导添加HDL文件、设置信号和接口添加软件,最终生成包含描述文件、用户存放硬件描述文件的文件夹以及用来包含HAL软件文件的HAL文件夹。 2.4构建Nios系统 构建好的内核文件在QuartusⅡ中编译,生成pof配置文件下载到E2PROM芯片中,接下来就可以使用NiosIDE开发环境编辑用户程序,以及通过JTAGBlaster或者USBBlaster在目标板上对应用程序进行调试。 3自定制外设PWM在嵌入式智能小车监控系统中的应用 智能小车监控系统设计应用周立功公司SmartSoPC核心板,FPGA为Altera公司的EPlC12,NiosⅡ处理器作为嵌入式CPU,机器人车电机共有两个,左轮电机和右轮电机。该部分包括电机驱动电路和电机控制电路,即左电机的驱动与控制以及右电机的驱动与控制。驱动电路采用CTMicroelectronics公司的大功率直流电机驱动芯片L289,调速控制采用PWM来控制汽车的前进速度,由FPGA写入控制字,可得到不同占空比的PWM驱动信号,此PWM信号送人电机驱动芯片的控制端来调节速度。调用电机驱动程序,改变PWM占空比,输出PWM波,实现电机的速度控制。用PWM信号控制直流电动机速度,频率较低时,电动机不会稳定运转,频率较高时,PWM信号的驱动效率降低。经过多次实际电路的测试,调试结果显示当频率在500~1000Hz时,效果较好。部分C语言控制代码如下: 4结语 NiosⅡ嵌入式处理器是用户可配制的通用RISC嵌入式处理器,是一个非常灵活和强大的处理器。基于此种技术的嵌入式系统设计可以方便地将一般设备和自定义设备模块集成到系统中,丰富了接口资源,从而能使用户快速地开发一个自定制片上系统,提高了效率,缩短了开发周期。本文通过自定制PWM外围设备的方法,并通过硬件测试证明了方案的可行性和正确性,希望能够为采用NiosⅡ处理器的开发人员提供一些方法和建议。
  • 热度 26
    2013-9-11 11:23
    2011 次阅读|
    4 个评论
    玩单片机的历史算是悠久了,从8031开始直到最近的FPGA之类的,也看了网上许多介绍给新手的文章,如何开始单片机.我想先采用PIC的16F873A这款RISC结构的单片机进行如何玩单片机讲讲个人的经验,也许介绍的方法非常苯?为什么呢?因为总是从手册先看起,而后开始动手.理解了再进行.苯是苯,但非常扎实,以后再玩起他的就轻架路熟了. 计划先从看手册开始,如果有中文的提供中文的,没有提供英文的,并且指出看那些后再继续.本文以最后用LCD显示测量电压或测频率数值作为最后的小制作作品,以满足成就感的"虚荣心".不过话说回来,谁不愿意玩了半天没有一点成就感呢?
  • 热度 22
    2013-5-3 18:17
    1500 次阅读|
    0 个评论
    软件预读机制由来已久,首先实现预读指令的处理器是Motorola的88110处理器,这颗处理器首先实现了“touch load”指令,这条指令是PowerPC处理器dcbt指令 的雏形。88110处理器是Motorola第一颗RISC处理器,具有里程碑意义,这颗处理器从内核到外部总线的设计都具有许多亮点。这颗处理器是Motorola对PowerPC架构做出的巨大贡献,PowerPC架构中著名的60X总线也源于88110处理器。 后来绝大多数处理器都采用这类指令进行软件预读,Intel在i486处理器中提出了Dummy Read指令,这条指令也是后来x86处理器中PREFETCHh指令 的雏形。 这些软件预读指令都有一个共同的特点,就是在处理器真正需要数据之前,向存储器发出预读请求,这个预读请求 不需要等待数据真正到达存储器之后,就可以执行完毕。从而处理器可以继续执行其他指令,以实现存储器访问与处理器运算同步进行,从而提高了程序的整体执行效率。由此可见,处理器采用软件预读可以有效提高程序的执行效率。我们考虑源代码3‑1所示的实例。 源代码3‑1没有采用软件预读机制的程序 3.4.3 软件预读 软件预读机制由来已久,首先实现预读指令的处理器是Motorola的88110处理器,这颗处理器首先实现了“touch load”指令,这条指令是PowerPC处理器dcbt指令 的雏形。88110处理器是Motorola第一颗RISC处理器,具有里程碑意义,这颗处理器从内核到外部总线的设计都具有许多亮点。这颗处理器是Motorola对PowerPC架构做出的巨大贡献,PowerPC架构中著名的60X总线也源于88110处理器。 后来绝大多数处理器都采用这类指令进行软件预读,Intel在i486处理器中提出了Dummy Read指令,这条指令也是后来x86处理器中PREFETCHh指令 的雏形。 这些软件预读指令都有一个共同的特点,就是在处理器真正需要数据之前,向存储器发出预读请求,这个预读请求 不需要等待数据真正到达存储器之后,就可以执行完毕。从而处理器可以继续执行其他指令,以实现存储器访问与处理器运算同步进行,从而提高了程序的整体执行效率。由此可见,处理器采用软件预读可以有效提高程序的执行效率。我们考虑源代码3‑1所示的实例。 源代码3‑1没有采用软件预读机制的程序 int ip, a , b ; for (i = 0; i N; i++) ip = ip + a *b ; 这个例子在对数组进行操作时被经常使用,这段源代码的作用是将int类型的数组a和数组b的每一项进行相乘,然后赋值给ip,其中数组a和b都是Cache行对界的。源代码3‑1中的程序并没有使用预读机制进行优化,因此这段程序在执行时会因为a 和b 中的数据不在处理器的Cache中,而必须启动存储器读操作。因此在这段程序在执行过程中,必须要等待存储器中的数据后才能继续,从而降低了程序的执行效率。为此我们将程序进行改动,如源代码3‑2所示。 源代码3‑2 采用软件预读机制的程序 int ip, a , b ; for (i = 0; i N; i++) { fetch(a ); fetch(b ); ip = ip + a *b ; } 以上程序对变量ip赋值之前,首先预读数组a和b,当对变量ip赋值时,数组a和b中的数据已经在Cache中,因而不需要进行再次进行存储器操作,从而在一定程度上提高了代码的执行效率。以上代码仍然并不完美,首先ip,a 和b 并没有被预读,其次在一个处理器,预读是以Cache行为单位进行的,因此对a ,a 进行预读时都是对同一个Cache行进行预读 ,从而这段代码对同一个Cache行进行了多次预读,从而影响了执行效率。为此我们将程序再次进行改动,如源代码3‑3所示。 源代码3‑3软件预读机制的改进程序 int ip, a , b ; fetch(ip); fetch(a ); fetch(b ); for (i = 0; i N-4; i+=4) { fetch(a ); fetch(b ); ip = ip + a *b ; ip = ip + a *b ; ip = ip + a *b ; ip = ip + a *b ; } for (; i N; i++) ip = ip + a *b ; 对于以上这个例子,采用这种预读方法可以有效提高执行效率,对此有兴趣的读者可以对以上几个程序进行简单的对比测试。但是提醒读者注意,有些较为先进的编译器,可以自动的加入这些预读语句,程序员可以不手工加入这些预读指令。实际上源代码3‑3中的程序还可以进一步优化。这段程序的最终优化如源代码3‑4所示。 源代码3‑4软件预读机制的改进程序 int ip, a , b ; fetch( ip); for (i = 0; i 12; i += 4){ fetch( a ); fetch( b ); } for (i = 0; i N-12; i += 4){ fetch( a ); fetch( b ); ip = ip + a *b ; ip = ip + a *b ; ip = ip + a *b ; ip = ip + a *b ; } for ( ; i N; i++) ip = ip + a *b ; 因为我们还可以对ip、数据a和b进行充分预读之后;再一边预读数据,一边计算ip的值;最后计算ip的最终结果。使用这种方法可以使数据预读和计算充分并行,从而优化了整个任务的执行时间。 由以上程序可以发现,采用软件预读机制可以有效地对矩阵运算进行优化,因为矩阵运算进行数据访问时非常有规律,便于程序员或编译器进行优化,但是并不是所有程序都能如此方便地使用软件预读机制。此外预读指令本身也需要占用一个机器周期,在某些情况下,采用硬件预读机制更为合理。 3.4.4 硬件预读 采用硬件预读的优点是不需要软件进行干预,也不需要浪费一条预读指令来进行预读。但硬件预读的缺点是预读结果有时并不准确,有时预读的数据并不是程序执行所需要的。在许多处理器中这种硬件预读通常与指令预读协调工作。硬件预读机制的历史比软件预读更为久远,在IBM 370/168处理器系统中就已经支持硬件预读机制。 大多数硬件预读仅支持存储器到Cache的预读,并在程序执行过程中,利用数据的局部性原理进行硬件预读。其中最为简单的硬件预读机制是OBL(One Block Lookahead)机制,采用这种机制,当程序对数据块b进行读取出现Cache Miss时,将数据块b从存储器更新到Cache中,同时对数据块b+1也进行预读并将其放入Cache中;如果数据块b+1已经在Cache中,将不进行预读。 这种OBL机制有很多问题,一个程序可能只使用数据块b中的数据,而不使用数据块b+1中的数据,在这种情况下,采用OBL预读机制没有任何意义。而且使用这种预读机制时,每次预读都可能伴随着Cache Miss,这将极大地影响效率。有时预读的数据块b+1会将Cache中可能有用的数据替换出去,从而造成Cache污染。有时仅预读数据块b+1可能并不足够,有可能程序下一个使用的数据块来自数据块b+2。 为了解决OBL机制存在的问题,有许多新的预读方法涌现出来,如“tagged预读机制”。采用这种机制,将设置一个“tag位”,处理器访问数据块b时,如果数据块b没有在Cache中命中,则将数据块b从存储器更新到Cache中,同时对数据块b+1进行预读并将其放入Cache中;如果数据块b已经在Cache中,但是这个数据块b首次被处理器使用,此时也将数据块b+1预读到Cache中;如果数据块b已经在Cache中,但是这个数据块b已经被处理器使用过,此时不将数据块b+1预读到Cache中。 这种“tagged预读机制”还有许多衍生机制,比如可以将数据块b+1,b+2都预读到Cache中,还可以根据程序的执行信息,将数据块b-1,b-2预读到Cache中。 但是这些方法都无法避免因为预读而造成的Cache污染问题,于是Stream buffer机制被引入。采用该机制,处理器可以将预读的数据块放入Stream Buffer中,如果处理器使用的数据没有在Cache中,则首先在Stream Buffer中查找,采用这种方法可以消除预读对Cache的污染,但是增加了系统设计的复杂性。 与软件预读机制相比,硬件预读机制可以根据程序执行的实际情况进行预读操作,是一种动态预读方法;而软件预读机制需要对程序进行静态分析,并由编译器自动或者由程序员手工加入软件预读指令来实现。 3.4.5 PCI 总线的预读机制 在一个处理器系统中,预读的目标设备并不仅限于存储器,程序员还可以根据实际需要对外部设备进行预读。但并不是所有的外部设备都支持预读,只有“well-behavior”存储器支持预读。处理器使用的内部存储器,如基于SDRAM、DDR-SDRAM或者SRAM的主存储器是“well-behavior”存储器,有些外部设备也是“well-behavior”存储器。这些well-behavior存储器具有以下特点。 (1) 对这些存储器设备进行读操作时不会改变存储器的内容。显然主存储器具有这种性质。如果一个主存储器的一个数据为0,那么读取这个数据100次也不会将这个结果变为1。但是在外部设备中,一些使用存储器映像寻址的寄存器具有读清除的功能。比如某些中断状态寄存器 。当设备含有未处理的中断请求时,该寄存器的中断状态位为1,对此寄存器进行读操作时,硬件将自动地把该中断位清零,这类采用存储映像寻址的寄存器就不是well-behavior存储器。 (2) 对“well-behavior”存储器的多次读操作,可以合并为一次读操作。如向这个设备的地址n,n+4,n+8和n+12地址处进行四个双字的读操作,可以合并为对n地址的一次突发读操作(大小为4个双字)。 (3) 对“well-behavior”存储器的多次写操作,可以合并为一次写操作。如向这个设备的地址n,n+4,n+8和n+12地址处进行四个双字的写操作,可以合并为对n地址的一次突发写操作。对于主存储器,进行这种操作不会产生副作用,但是对于有些外部设备,不能进行这种操作。 (4) 对“well-behavior”的存储器写操作,可以合并为一次写操作。向这个设备的地址n,n+1,n+2和n+3地址处进行四个单字的写操作,可以合并为对n地址的一次DW写操作。对主存储器进行这种操作不会出现错误,但是对于有些外部设备,不能进行这种操作。 如果外部设备满足以上四个条件,该外部设备被称为“well-behavior”。PCI配置空间的BAR寄存器中有一个“Prefectchable”位,该位为1时表示这个BAR寄存器所对应的存储器空间支持预读。PCI总线的预读机制需要HOST主桥、PCI桥和PCI设备的共同参与。在PCI总线中,预读机制需要分两种情况进行讨论,一个是HOST处理器通过HOST主桥和PCI桥访问最终的PCI设备;另一个是PCI设备使用DMA机制访问存储器。 PCI总线预读机制的拓扑结构如图3‑12所示。 由上图所示,HOST处理器预读PCI设备时,需要经过HOST主桥,并可能通过多级PCI桥,最终到达PCI设备,在这个数据传送路径上,有的PCI桥支持预读,有的不支持预读。而PCI设备对主存储器进行预读时也将经过多级PCI桥。PCI设备除了可以对主存储器进行预读之外,还可以预读其他PCI设备,但是这种情况在实际应用中极少出现,本节仅介绍PCI设备预读主存储器这种情况。 1 HOST处理器预读PCI设备 PCI设备的BAR寄存器可以设置预读位,首先支持预读的BAR寄存器空间必须是一个Well-behavior的存储器空间,其次PCI设备必须能够接收来自PCI桥和HOST主桥的MRM(Memory Read Multiple)和MRL(Memory Read Line)总线事务。 如果PCI设备支持预读,那么当处理器对这个PCI设备进行读操作时,可以通过PCI桥启动预读机制(该PCI桥也需要支持预读),使用MRM和MRL总线事务,对PCI设备进行预读,并将预读的数据暂时存放在PCI桥的预读缓冲中。 之后当PCI主设备继续读取PCI设备的BAR空间时,如果访问的数据在PCI桥的预读缓冲中,PCI桥可以不对PCI设备发起存储器读总线事务,而是直接从预读缓冲中获取数据,并将其传递给PCI主设备。当PCI主设备完成读总线事务后,PCI桥必须丢弃预读的数据以保证数据的完整性。此外当PCI桥预读的地址空间超越了PCI设备可预读BAR空间边界时,PCI设备需要“disconnect”该总线事务。 如果PCI桥支持“可预读”的存储器空间,而且其下挂接的PCI设备BAR空间也支持预读时,系统软件需要从PCI桥“可预读”的存储器空间中为该PCI设备分配空间。此时PCI桥可以将从PCI设备预读的数据暂存在PCI桥的预读缓冲中。 PCI总线规定,如果下游PCI桥地址空间支持预读,则其上游PCI桥地址空间可以支持也可以不支持预读机制。如图3‑12所示,如果PCI桥B管理的PCI子树使用了可预读空间时,PCI桥A可以不支持可预读空间,此时PCI桥A只能使用存储器读总线事务读取PCI设备,而PCI桥B可以将这个存储器读总线事务转换为MRL或者MRM总线事务,预读PCI设备的BAR空间(如果PCI设备的BAR空间支持预读),并将预读的数据保存在PCI桥B的数据缓冲中。 但是PCI总线不允许PCI桥A从其“可预读”的地址空间中,为PCI桥B的“不可预读”区域预留空间,因为这种情况将影响数据的完整性。 大多数HOST主桥并不支持对PCI设备的预读,这些HOST主桥并不能向PCI设备发出MRL或者MRM总线事务。由于在许多处理器系统中,PCI设备是直接挂接到HOST主桥上的,如果连HOST主桥也不支持这种预读,即便PCI设备支持了预读机制也没有实际作用。而且如果PCI设备支持预读机制,硬件上需要增加额外的开销,这也是多数PCI设备不支持预读机制的原因。 尽管如此本节仍需要对HOST处理器预读PCI设备进行探讨。假设在图3‑12所示的处理器系统中,HOST主桥和PCI桥A不支持预读,而PCI桥B支持预读,而且处理器的Cache行长度为32B(0x20)。 如果HOST处理器对PCI设备的0x8000-0000~0x8000-0003这段地址空间进行读操作时。HOST主桥将使用存储器读总线事务读取PCI设备的“0x8000-0000~0x8000-0003这段地址空间”,这个存储器读请求首先到达PCI桥A,并由PCI桥A转发给PCI桥B。 PCI桥B发现“0x8000-0000~0x8000-0003这段地址空间”属于自己的可预读存储器区域,即该地址区域在该桥的Prefetchable Memory Base定义的范围内,则将该存储器读请求转换为MRL总线事务,并使用该总线事务从PCI设备 中读取0x8000-0000~0x8000-001F这段数据,并将该数据存放到PCI桥B的预读缓冲中。MRL总线事务将从需要访问的PCI设备的起始地址开始,一直读到当前Cache行边界。 之后当HOST处理器读取0x8000-0004~0x8000-001F这段PCI总线地址空间的数据时,将从PCI桥B的预读缓冲中直接获取数据,而不必对PCI设备进行读取。 2 PCI设备读取存储器 PCI设备预读存储器地址空间时,需要使用MRL或者MRM总线事务。与MRL总线周期不同,MRM总线事务将从需要访问的存储器起始地址开始,一直读到下一个Cache行边界为止。 对于一个Cache行长度为32B(0x20)的处理器系统,如果一个PCI设备对主存储器的0x1000-0000~0x1000-0007这段存储器地址空间进行读操作时,由于这段空间没有跨越Cache行边界,此时PCI设备将使用MRL总线事务对0x1000-0000~0x1000-001F这段地址区域发起存储器读请求。 如果一个PCI设备对主存储器的0x1000-001C~0x1000-0024这段存储器地址空间进行读操作时,由于这段空间跨越了Cache行边界,此时PCI设备将使用MRM总线事务对0x1000-001C~0x1000-002F这段地址空间发起存储器读请求。 在图3‑12所示的例子中,PCI设备读取0x1000-001C~0x1000-0024这段存储器地址空间时,首先将使用MRM总线事务发起读请求,该请求将通过PCI桥B和A最终到达HOST主桥。HOST主桥 将从主存储器中读取0x1000-001C~0x1000-002F这段地址空间的数据。如果PCI桥A也支持下游总线到上游总线的预读,这段数据将传递给PCI桥A;如果PCI桥A和B都支持这种预读,这段数据将到达PCI桥B的预读缓冲。 如果PCI桥A和B都不支持预读,0x1000-0024~0x1000-002F这段数据将缓存在HOST主桥中,HOST主桥仅将0x1000-001C~0x1000-0024这段数据通过PCI桥A和B传递给PCI设备。之后当PCI设备需要读取0x1000-0024~0x1000-002F这段数据时,该设备将根据不同情况,从HOST主桥、PCI桥A或者B中获取数据而不必读取主存储器。值得注意的是,PCI设备在完成一次数据传送后,暂存在HOST主桥中的预读数据将被清除。PCI设备采用这种预读方式,可以极大提高访问主存储器的效率。 PCI总线规范有一个缺陷,就是目标设备并不知道源设备究竟需要读取或者写入多少个数据。例如PCI设备使用DMA读方式从存储器中读取4KB大小的数据时,只能通过PCI突发读方式,一次读取一个或者多个Cache行。 假定PCI总线一次突发读写只能读取32B大小的数据,此时PCI设备读取4KB大小的数据,需要使用128次突发周期才能完成全部数据传送。而HOST主桥只能一个一个的处理这些突发传送,从而存储器控制器并不能准确预知何时PCI设备将停止读取数据。在这种情况下,合理地使用预读机制可以有效地提高PCI总线的数据传送效率。 我们首先假定PCI设备一次只能读取一个Cache行大小的数据,然后释放总线,之后再读取一个Cache行大小的数据。如果使用预读机制,虽然PCI设备在一个总线周期内只能获得一个Cache行大小的数据,但是HOST主桥仍然可以从存储器获得2个Cache行以上的数据,并将这个数据暂存在HOST主桥的缓冲中,之后PCI设备再发起突发周期时,HOST主桥可以不从存储器,而是从缓冲中直接将数据传递给PCI设备,从而降低了PCI设备对存储器访问的次数,提高了整个处理器系统的效率。 以上描述仅是实现PCI总线预读的一个例子,而且仅仅是理论上的探讨。实际上绝大多数半导体厂商都没有公开HOST主桥预读存储器系统的细节,在多数处理器中,HOST主桥以Cache行为单位读取主存储器的内容,而且为了支持PCI设备的预读功能HOST主桥需要设置必要的缓冲部件,这些缓冲的管理策略较为复杂。 目前PCI总线已经逐渐退出历史舞台,进一步深入研究PCI桥和HOST主桥,意义并不重大,不过读者依然可以通过学习PCI体系结构,获得处理器系统中有关外部设备的必要知识,并以此为基础,学习PCIe体系结构。 3.5 小结 本章重点介绍了PCI总线的数据交换。其中最重要的内容是与Cache相关的PCI总线事务和预读机制。虽然与Cache相关的PCI总线事务并不多见,但是理解这些内容对于理解PCI和处理器体系结构,非常重要。 为简便起见,下文将转移指令成功进行转移称为“Taken”;而将不进行转移称为“Not Taken”。 假定从访问Cache到发现Cache Miss需要一个时钟周期。 PowerPC处理器使用dcbt指令,而x86处理器使用PREFETCHh指令,实现这种软件预读。 假定从Cache中获得数据需要一个时钟周期。 dcbt指令是PowerPC处理器的一条存储器预读指令,该指令可以将内存中的数据预读到L1或者L2 Cache中。 PREFETCHh指令是x86处理器的一条存储器预读指令。 预读指令在一个时钟周期内就可以执行完毕。 假定这个处理器系统的Cache行长度为4个双字,即128位。 假设中断状态寄存器支持读清除功能。 此时PCI设备的这段区域一定是可预读的存储器区域。 假设HOST主桥读取存储器时支持预读,多数HOST主桥都支持这种预读。
相关资源