技术论坛

  • FPGA

    Xilinx大学计划官方FPGA开发板(DIGILENT全球唯一原厂) & Pmods积木式传感器

    发帖数

    351
    涂鸦+代码教你如何构建一个简单的最小神经网络
    闲来无事,想尝试做一个简单的最小神经网络,通过训练来让其识别一些东西。在这篇文章里,我将试着通过结合涂鸦与代码的方式来更为直观地向大家解释这一最小神经网络的构建过程。好了,让我们开始吧!01很多神经网络的术语都是从生物学的角度出发并赋予其意义的,所以让我们从最顶层的一番小科普开始:大脑是十分复杂的,但总的来说可以将之分为几个基本的运作部分:刺激-输入-处理-输出当然,刺激也可以通过内在产生(如感知或想法):我们来看一下基本的、简化的大脑构造。下图右侧为一个大脑的横切面,其中四周灰色的部分为神经元层,白色的部分为轴突:大脑令人惊讶之处其实就是“布线”神经元是大脑计算的基本单位,它接收和整合来自其它神经元的化学信号。取决于多种因素,它要么什么都不做,要么产生电信号或动作电位,其反过来通过触发信号通知其它相连接的神经元:做梦,记忆,想法,自我调节运动,反射以及你所想所做的一切都是通过这个过程产生的:数以百万计甚至数十亿的神经元以不同的速率发射并建立连接,从而产生不同的并行运行子系统,并基于此构建了一个生物意义上的神经网络。当然,上述是一种泛化和简化的解释。但现在我们可以描述一个最小的生物神经网络是什么了,以手指被图钉扎到而产生应激反应为例:皮肤被图钉扎到-感觉神经元-中间神经元-运动神经元-肌肉产生应激反应:用图形的方式可以正式地描述为:为了在当前这一阶段尽可能解释地简单,圆圈代表神经元,它们之间存在连接,连接线表示信息从左到右的向前移动。第一个神经元目前正在发射,在此通过阴影来指代。它会被赋予一个数字(当它正在发射时为1,否则为0)。神经元之间的数字表示连接权重。如果说上一张图代表了神经网络的一个时刻,而对神经网络更准确的描述将被分成时间段:02在构建神经网络之前,我们需要了解权重是如何影响神经元以及神经元是如何学习的。让我们从一只兔子(一只真实的实验兔子)和一个经典的调节实验来说起:当受到无害的吹气时,像人类一样兔子通常会眨眼:我们可以用一个简单的图表来建模这个行为:就像之前的图表一样,上图显示的只是当兔子感应到空气的那一刻,在此我们将它编码为一个布尔值。在此基础上,现在我们计算第二个神经元是否基于权重值进行触发,如果权重为1,感觉神经元正在触发我们眨眼,如果低于1,则不眨眼。换句话说,我们的第二个神经元有一个阈值1。让我们来引入另一个元素,当兔子接收到一个无害的听觉声音:我们可以用以下方式模拟兔子缺乏兴趣:可以看出,唯一不同的是权重现在是0,所以兔子不会有眨眼,至少现在还没有。那么现在让我们训练我们的兔子根据混合刺激命令来眨眼(混合听觉声音与吹气):重要的一点是,每个事件都发生在不同的时间点,因此图表看起来会是这样:声音并没有产生任何影响,但是吹气仍然会引起兔子眨眼的反应,这里要注意的要点是我们通过权重乘以刺激(上图中红色)来表示这一点。到这里,我们可以将在一串复杂行为中的“学习”,简化定义为神经网络中连接的神经元之间时间权重的递增变化。为了训练我们的兔子,我们必须得重复这个过程:下图对应的是初始状态和前3次实验:请注意,在每次实验之后,声音的权重会增加(红色),这个数字在这一点上是任意的-我选择了0.30,但它可以是任何数字,甚至是负数。直到第三次实验,兔子都有着相同的行为。但是在第四次实验之后,一些新的事情发生了......我们发现了新的行为。这次实验中,我们暂停了吹气,但兔子在听到声音后仍然眨了眼睛!对这一新行为的解释如下图:也就是说,现在我们的兔子已经被训练出可以在听到声音后就眨眼了。注:真实实验中,通过在几个星期或更长时间内进行大约60次实验即可引起兔子的上述反应03好了,现在让我们离开大脑和兔子的“生物世界”,而是将上述我们已经学到的一些知识应用于人工神经网络的构建。我们要做的第一件事是去尝试定义一个简单的问题。假设有一个4个按键的机器,如果你按下正确的按键则会给你提供食物。为此,目标对象需要学习去按哪个按键才能够获取食物:我们可以通过以下图形方式来表示按下按键:这一问题很容易在整体上理解,所以让我们看看所有可能的结果:现实中,按下按键3就能获得食物为了用代码创建一个神经网络,我们首先需要一个模型或图形来匹配它。对于目前的这一问题,我们可以用下图来对其生物表象进行松散地模拟:这一神经网络所做的可以简单理解为接收一个输入(在此例中即为感知哪个按键被按下),然后通过权重修改上述输入,最后根据所添加的图层返回输出。这听起来可能有点复杂,那么就让我们来看看我们的模型是如何来表示按钮被按下的:注意所有权重都是零,所以这一神经网络处于空白状态,但是其完全连接,就像新生儿一样因此,我们将外部事件映射到神经网络输入层并计算输出,这个输出可能符合也可能不符合实际结果(此处即,能“吃鸡”的正确按钮)。但现在我们先忽略这一点,并开始用计算机友好的方式来编写这个问题的代码。04让我们从输入和权重开始(这里我将使用Javascrit):varinuts=[0,1,0,0];varweights=[0,0,0,0];//wecancallthesevectorsforconvenience.下一步是创建一个函数,它接收这些输入和权重并计算输出;会是这样一个功能:functionevaluateNeuralNetwork(inutVector,weightVector){varresult=0;inutVector.forEach(function(inutValue,weightIndex){layerValue=inutValue*weightVector[weightIndex];result+=layerValue;});return(result.toFixed(2));}//Mightlookcomlex,butallitdoesismultilyweight/inutairsand正如所料,如果我们运行上述代码,我们会得到与我们上图模型相同的结果...evaluateNeuralNetwork(inuts,weights);//0.00代码实例可参考:htts://codeen.io/k3no/en/GWyJgP下一步对我们神经网络的升级则是让其将自己的输出结果与真实情况进行比对。让我们先把这个特定的真实情况编码成一个变量:为了检测是否不匹配(以及有多少不匹配),我们将添加一个错误函数:Error=Reality-NeuralNetOutut有了这两个部分之后,我们现在可以来判断我们的神经网络了,比对结果错误如下图:以及更为重要的,比对结果正确图(可以吃鸡):到这里,现在我们可以明确知道我们的神经网络模型在何种情况下输出的结果会不work(并且在数值上会差多少),这很好!很好的原因是因为现在我们可以使用错误的反馈结果来指导我们的学习。这里,如果我们对我们的“错误函数”做一些小的改变,会让这一切显得更有意义,如下所示:Error=DesiredOutut-NeuralNetOutut这一微小但重要的改变在这里可以默认理解为:我们将使用以前观察到的结果与未来的表现来进行比对(换句话说,与“学习”结果进行比对,后面很快会讲到)。这一逻辑同样适用于现实生活,因为真理(正确的结果)往往是会重复显现的。所以,我们可以将上述策略理解为一种自我进化策略。理解了以上逻辑之后,下面对于示例代码的修改就变得简单了,我们只需要添加一个新变量:Error=varinut=[0,0,1,0];varweights=[0,0,0,0];vardesiredResult=1;以及新的函数:functionevaluateNeuralNetError(desired,actual){return(desired—actual);}//AfterevaluatingboththeNetworkandtheErrorwewouldget://"NeuralNetoutut:0.00Error:1"代码实例可参考:htts://codeen.io/k3no/en/dvaGX好了,到这里,对于我们之前的讲解做一下友情回顾:我们从定义一个问题开始,然后针对其以神经元生物网络的形式建立一个简单的模型。接着,我们将这一模型的输出结果与真实结果/期望结果做比对,并通过某种方式来修正错误的比对结果。这一过程对于计算机和人类来说即为学习。05那么如何来训练一个神经网络呢?无论是对于生物神经网络还是人工智能来说,“学习”的基本原则都可以理解为基于重复实验与学习算法。对于这两个关键词,我们来一一解决。让我们先从学习算法开始。本质上,学习算法可以理解为在一次经历之后神经元的物理和化学特性所发生的变化:在代码和我们的模型中,学习算法可以简单理解为我们将随着时间的推移而改变某些东西。秉承着简单易懂的原则,让我们先添加一个变量:varlearningRate=0.20;//biggerrate,biggerfasterlearnings:)我们将改变什么?与之前兔子的例子一样,我们将改变权重,特别是我们想要的结果的权重:如何对这样一个算法进行编程不同人会有不同的选择。为简单起见,我只是增加了学习速度的权重,在这里它是一个函数:functionlearn(inutVector,weightVector){weightVector.forEach(function(weight,index,weights){if(inutVector[index]>0){weights[index]=weight+learningRate;}});}使用这个学习函数,在每个学习周期(或实验)前后,都会将我们的学习速率添加到活动神经元的权重向量中,其结果如下://Originalweightvector:[0,0,0,0]//NeuralNetoutut:0.00Error:1learn(inut,weights);//NewWeightvector:[0,0.20,0,0]//NeuralNetoutut:0.20Error:0.8//Ifitisnotaarentlyobvious,aNeuralNetoututcloserto1//(chickendinner)iswhatwewant,soweareheadingintheright//direction代码实例可参考:htt://codeen.io/k3no/en/qrJoXO好了,我们正朝着正确的方向前进,现在我们需要做的最后一步就是重复实验。这不难,本质上我们只是去一遍又一遍地做一些事情,而在代码中我们只是指定了实验的次数:vartrials=6;并根据我们所定义的实验次数,将我们的学习函数应用于我们的神经网络中,即这一训练函数为:functiontrain(trials){for(i=0;i<trials;i++){neuralNetResult=evaluateNeuralNetwork(inut,weights);learn(inut,weights);}}我们的最终读数为:NeuralNetoutut:0.00Error:1.00WeightVector:[0,0,0,0]NeuralNetoutut:0.20Error:0.80WeightVector:[0,0,0.2,0]NeuralNetoutut:0.40Error:0.60WeightVector:[0,0,0.4,0]NeuralNetoutut:0.60Error:0.40WeightVector:[0,0,0.6,0]NeuralNetoutut:0.80Error:0.20WeightVector:[0,0,0.8,0]NeuralNetoutut:1.00Error:0.00WeightVector:[0,0,1,0]//ChickenDinner!代码实例可参考:htts://codeen.io/k3no/en/dvBZLe?editors=0012我们现在得到一个权重向量,只有当输入向量与真实结果(第三个按钮向下)一致时,才会导致输出结果1(吃鸡)的产生。06我们刚刚创建的这个东西能带给我们什么?在这一特定的案例中,我们的神经网络(在被训练之后)可以识别或区分输入之间的差异,并告诉你哪一个输入会产生一个所希望的输出结果(当然,我们仍需要为特定的情况进行编程):除此之外,我们得到了一个比例模型,玩具或者说是学习工具,可以让我们进一步了解机器学习,神经网络和人工智能。EECS圈新工科不只是口号欢迎勾搭
    发布于 前天 16:42
  • 开源微控制器(LabVIEW支持)

    树莓派(Raspberry Pi)、BeagleBone Black、chipKIT

    发帖数

    42
    BeagleBone Black安装run-time问题
    按照自学里的步骤安装run-time出现问题了请大神们帮我看看是什么原因导致不往下进行提示run-time版本14.1-11可供安装点击安装run-time然后跳出图片上的这个让我点击EXPANDPARTITION按钮点击后就是一直是working也不往下执行了然后其他按钮都点击不了整整等了5个小时一直就是这个界面不往下走
    发布于 07-15
  • 口袋仪器

    OpenScope、Analog Discovery 2、Analog Discovery、Digital Discovery、Electronics Explorer

    发帖数

    45
    电子工程学霸君的口袋里,都有这么一款神秘私藏工具
    文|蒙面侠客硬件开发出问题的时候我们首先想到的工具是示波器、任意波形发生器、网络分析仪、频谱分析仪、数字总线分析仪等设备。还没有列举完这些仪器,想必你脑子里已经出现了一个试验台,上面罗列着各种价格不菲的高档仪器。作为电子攻城狮,你是否曾经或多或少遇到过类似的场景:同样是在同一起跑线上准备“屡起袖子搞点事情”,当你还在为去哪儿才能一次性借用到项目开发所需的多台实验室设备而烦恼时,时常你会发现,身边的那些学霸与技术大牛们,早已泰然自若地搞定了项目的一切,伴随着与学霸擦肩而过时对方所投来的淡定中略带得意的小眼神,让你心中顿时有一句那啥不知当讲不当讲...你以为,每一名电子工程学霸都是天生的?图样图森破了吧~~事实上,学霸们一定不曾告诉你,一个能放到他们牛仔裤口袋里的盒子就是他们行走江湖不湿身的秘籍。这个名为AnalogDiscovery2的绿色小盒,能集前文提到的所有常用仪器功能于一身,只要你身边有台笔记本电脑,就能在任意场合随时随地拥有一个强大的电子工程设计工作站!正是靠它,让多少学霸们无论是在实验室内还是在实验室外,都能在几乎所有环境中去随心所欲地搭建并测试他们的模拟和数字电路。本质上,AnalogDiscovery2是一款由Digilent公司所出品的迷你型USB示波器和多功能仪器,根据Digilent官方产品资料显示,其设计初衷就是为了让用户方便地测试、读取、生成、记录和控制各种混合信号电路:“作为一款和AnalogDevices联合开发并且获得Xilinx大学计划官方支持的便携式产品,AnalogDiscovery2小到可以轻而易举地放进你的口袋,但功能可以强大到足以替代一堆的实验室设备。无论是在实验室内还是在实验室外的环境下,AnalogDiscovery2都能够为工科生、业余爱好者或者电子发烧友提供一个随心所欲地基于模拟数字电路开展动手项目的口袋仪器实验室。”事实上,这款“学霸私藏工具”并不神秘,上图就是它的样子,拆解后可以看出,它只有大约三厘米宽,足够精致小巧到随身塞入口袋。出于一名电子发烧友的好奇与本能,本侠也入手了一款该产品,并在过去的一周拿到手把玩了一番,在这里分享一些使用感受。上图是到手的AnalogDiscovery2连接使用后的样儿。它具有100MPS双通道USB数字示波器,双通道任意函数发生器,16通道数字逻辑分析仪,信号源、可调电源、频谱分析仪、网络分析仪等十种仪器功能,并且性能参数强劲,足够在校学生与电子设计爱好者日常实验与项目的使用(详情可见:www.digilent.com.cn/roducts/roduct-ad2)。所有的这些功能,一定程度上得益于XilinxSartan-6FPGA的高性能和灵活性,配合十分容易上手的DigilentWaveForms软件平台(嗯,用了一下确认是完全免费的),充分发挥了该产品所集成的XilinxFPGA和AnalogDevices各器件的功能。下图为网上所找到的该产品的模块框图:把AnalogDiscovery2变成示波器,我们需要AnalogDiscoveryBNCAdaterBoard来进行扩展,扩展板如下所示。再通过最新WaveForms2015上位机的配合,对于硬件开发者来讲,即便你是一名基础小白,都能很快地将AnalogDiscovery2模块变成开发者需要的功能仪器,从而快速,精确地解决硬件开发过程中所遇上的问题。顺带提一句,除了简单易用的WaveForms之外,经谷歌出的一偏文章提示,本侠尝试了一下,发现AnalogDiscovery2还支持包括C语言、Python、Matlab、LabVIEW等多种语言的SDK、API哦~同时,在Digilent中文官网上,本侠发现了一系列为该产品配套的包括【快速入门教程视频】,【电路原理/模拟电路开课指南】,【上海交大/南京大学等国内知名高校的教学慕课】,【诸多大学生开源作品项目】在内的学习资源,可见该产品的生态圈着实丰富。总结:硬件开发者可以方便地通过一根简易的导线探针将AnalogDiscovery2的模块和数字输入输出连接到电路,还可以通过AnalogDiscoveryBNC适配器和BNC探针来达到同样的效果,以调用模拟/数字输入输出接口。再加上XilinxSartan-6FPGA的强悍的功能、灵活性以及配合AD/DA转换和多种模拟/数字信号处理模块,相信硬件开发者能够从AnalogDiscovery2中获得更多的快速、精确的解决问题的方法。
    发布于 11-22

创客圈

  • 创客小组(项目集散地)

    这里不仅有灵感与创意,更有实践、激情、与同道。创者无畏!

    发帖数

    22
    基于Basys3的2048小游戏
    首先十分感谢Digilent论坛提供的这次机会,我跟大家分享的是我设计的一款小游戏:基于Basys3的2048小游戏。游戏功能:游戏界面由4×4的16个方格组成,每个方格中可以存放一个数字。玩家通过操纵Basys3开发板的上下左右四个方向键和中央的reset键,控制方格中的数字移动。界面由VGA和Pmod接口oled两种方式显示。游戏成功时显示笑脸,失败时显示骷髅。游戏过程中,玩家每按动一次方向键,所有数字按照这个方向移动一次,该方向上相邻相同的数字合并为原来的2倍,并在反方向随机生成一个新的数字。玩家目标是在游戏中拼出2048或更高的数字,即为游戏成功。DIY动手指南:Ste1:材料准备硬件:Basys3开发板VGA连接线以及VGA显示器(可选)sh1106驱动的oled显示屏一块软件:Vivado2016.2Ste2:系统框架系统主要由以下几个模块构成,游戏主状态机、游戏数据寄存器{S16}、移动模块move、随机产生模块gen、随机数生成器ran、VGA驱动模块和oled驱动模块。Ste3:程序设计接下来分模块进行分析。1、按键去抖对每个按键设计了一个32位长的FIFO,按键值从低位进入直至高位溢出。每过10ms,FIFO被完全刷新一次,只有当32位为FFFFFFFFh时认为输入为1,00000000h时认为输入为0。2、游戏数据寄存器用4×4=16个4bit寄存器,存放16个格子中的数据,记为{S16},以【log2对数】形式存放。即如果格子中是512,则存放9;如果格子中是128,则存放7。特例是0用0来存放。这种存放的特点是,可以节约寄存器数量,而且原本的加法128+128=256可以用加1来表示:7+1=8。寄存器位置定义如下:3、游戏主状态机游戏主状态机中,主要操纵数据寄存器{S16}的数值,通过对这个寄存器中数值的改变来实现游戏的进行。状态机分为4个状态:检测按键+移动,产生随机数,游戏状态检测,游戏失败死循环。其中游戏状态检测时,检查当前游戏是否已经结束或成功,如果成功,游戏不中断,玩家可以继续下去,如果已经结束,则跳入游戏失败的死循环中,结束游戏。4、移动逻辑组合电路本游戏有4种移动方式,即上下左右,每次移动4条线,但本质都是相同的,只需要一个模块即可完成。如下图所示move(i3,i2,i1,i0,o3,o2,o1,o0)我们默认向右移动。(为什么呢?因为当我们调用这个模块时,可以以各种方向调用:如果向右移动,则调用move(15,14,13,12)向右,如果向左移动,则调用move(12,13,14,15)向右即可,还可以调用move{15,11,7,3}向下,调用move{1,5,9,13}向上等等。)那么向右移动时,用f3~f0判断这四位是否为空,通过对f3~f0的16种情况的mux来决定输出的值,如果有相同则合并后输出。(其实这个模块就是一个大mux)例如,下图所示,左图右移后,变为右图。再例如:2,2,4,8右移后变为0,4,4,8,再右移变为0,0,8,8再右移变为0,0,0,165、随机数生成器和随机产生模块随机数产生器为随机产生模块gen服务。随机数生成器产生3组随机数,分别为8bit,12bit和16bit。分别对应2空格、3空格和4空格的情况。例如,如果右移后的图片如下图所示,那么黄色格子里的2就是在最左列3空格情况下随机产生的一个位置。我们还是默认向右移动,那么最左边的四个格子(15,11,7,3)即可交给gen,在空白出产生一个随机位置的“2”。这里需要注意的是,2048游戏中规定必须是“有效移动”后才产生一个数字,以杜绝有投机的玩家一直按同一个方向键可以作弊的情况。这一逻辑只需要对上一步中move前后做一下对比即可。6、VGA显示模块640×480分辨率,25MHz的时钟信号。其中扫描时,将VGA坐标的后两位[1:0]舍去,即可将640×480像素变为160×120的色块。(注:源码中的VGA画图一段和oled画图一段看上去很复杂,其实是画点的方式比较奇怪,两种画法都是先将132x64的点阵水平划分为8条,每条8行,再以每列为1个byte的方式画出来。。。那么为什么要这么复杂呢?因为oled的sh1106驱动就是这么要求的,我先做了oled,后面vga就直接引用了~)Ste4:演示见视频~
    发布于 03-07
  • 竞赛 & 活动

    DIGILENT全可编程创新创业设计大赛(DDC)、江苏省虚拟仪器竞赛、极客DIY限时挑战等

    发帖数

    15
    特别活动 | Python on Everything 硬件项目挑战赛
    PythonforEverything!「Python+开源硬件」·创客项目设计主题活动▼PythonAI时代的头牌语言web开发、游戏开发、客户端开发...当这些软件应用领域逐渐被Python“玩坏了”之后凭借“语言简洁,无需编译,开发高效”的特性一场Python与开源硬件的邂逅悄然已成趋势人生苦短,我用Python当DIGILENT已为你准备好多款主流Python开发板当你的情敌暑期已在用Python加速项目设计开发不要告诉我们你还在家打王者荣耀暑期8月,DIGILENT有一个大胆的想法管它当讲不当讲「Python+开源硬件」·创客项目设计挑战赛Let'smakePythonforEverything!1先来一波DIGILENTPython支持开发板▼PYNQ世界上第一款支持Python的FPGA嵌入式开发板●主芯片:XilinxZynq-7020●Python开发战斗值:★★★★★●战力简介:支持开源的PYNQ项目,它直接对硬件底层进行的封装,用户借助封装库文件可以直接使用ython语言操作硬件I/O管脚等功能,不需要再使用复杂繁琐的开发工具,使用基于浏览器的JuyterNotebook工具就可以直接编辑工程代码。同时可轻松搭建开源的机器学习二值神经网络(BNN)。●了解详情:www.digilent.com.cn/roducts/ynq-z1▼Zedboard世界上第一款也是最为经典的XilinxZynqAPSoC开发板●主芯片:XilinxZynq-7020(双核ARMCortex™-A9)●Python开发战斗值:★★★★●战力简介:在Linux系统中配置Python3或Python2.7(如果使用的是Ubuntu,Python2,3已被预安装),即可用Python进行应用设计。调用驱动控制外设。环境配置步骤:1)安装Linux系统;2)安装Python;更新系统:$sudoat-getudate检查版本:$ython3-V3)安装所需的库;$iinstall$sc●了解详情:www.digilent.com.cn/roducts/roduct-zedboard-zynq-7000-arm-fga-soc-develoment-board▼Zybo享有“MiniZedboard”美誉的Zynq入门级训练板●主芯片:XilinxZynq-7010(双核ARMCortex™-A9)●Python开发战斗值:★★★★●战力简介:在Linux系统中配置Python3或Python2.7(如果使用的是Ubuntu,Python2,3已被预安装),即可用Python进行应用设计。调用驱动控制外设。环境配置步骤:1)安装Linux系统;2)安装Python;更新系统:$sudoat-getudate检查版本:$ython3-V3)安装所需的库;$iinstall$sc●了解详情:www.digilent.com.cn/roducts/roduct-zybo-zynq-7000-arm-fga-soc-trainer-board▼Arty-Z7全新问世兼容Arduino接口的Zynq-7000开源创客开发板●主芯片:XilinxZynq-7020/10(双核ARMCortex™-A9)●Python开发战斗值:★★★★●战力简介:在Linux系统中配置Python3或Python2.7(如果使用的是Ubuntu,Python2,3已被预安装),即可用Python进行应用设计。调用驱动控制外设。环境配置步骤:1)安装Linux系统;2)安装Python;更新系统:$sudoat-getudate检查版本:$ython3-V3)安装所需的库;$iinstall$sc●了解详情:www.digilent.com.cn/roducts/roduct-arty-z720-asoc-zynq-7000-develoment-board-for-makers-and-hobbyists▼树莓派2为Python编程而生的Geek最爱嵌入式开发板●主芯片:900MHz双核ARMCortex-A7CPU●Python开发战斗值:★★★★★●战力简介:在早先BBC的一篇采访中,RasberryPi的创始人之一EbenUton就曾提到,RasberryPi的命名中,Pi所指的就是Python。树莓派基金会提供了基于ARM的Debian和ArchLinux的发行版供大众下载。还计划提供支持Python作为主要编程语言,支持Java、BBCBASIC(通过RISCOS映像或者Linux的"BrandyBasic"克隆)、C和Perl等编程语言。●了解详情:www.digilent.com.cn/roducts/roduct-labview-for-rasberry-i-2▼BeagleBoneBlack为数不多可以在10秒内启动Linux的开发板,三大开源硬件平台之一●主芯片:AM335x1GHzARMCortex-A8●Python开发战斗值:★★★★★●战力简介:不可多得的支持Python编程的实战力器,默认安装有Python2.7.3以及相应的Python库。●了解详情:www.digilent.com.cn/roducts/roduct-labview-for-beaglebone-black2活动参与方式与福利01挑战任务基于任意一款DIGILENTPython支持开发板,在为期四周的时间内(9月8日前)使用Python语言编写一个应用设计。应用主题不限,但需要利用硬件外设,如Pmod模块、摄像头,或板上自带的IO/WiFi模块/传感器等。02奖项设置●最佳「Python+开源硬件」设计作品奖【1名】获赠全新DigilentPYNQ开发板一块受邀参与2017DIGILENT创客夏令营●优秀创意作品奖【2名】获赠全新DigilentchiKITWF32嵌入式开发板一块受邀参与2017DIGILENT创客夏令营●实际作品提交参与奖【若干】所有最终按照活动要求提交作品的挑战者,都将获得人气FPGA教材一套03参与方式&am;项目提交●参与方式:加入“PythonforEverything”创客小组传送门:www.digilent.com.cn/makerhubs/ython-on-everything.html●项目提交:项目完成后,进入上述页面”发布项目”●截止时间:9月8日中午12时04指定软硬平台指定硬件(优秀创意项目DIGILENT提供免费租借):●PYNQ/Zedboard/Zybo/Arty-Z7/RasberryPi2/BeagleBoneBlack指定软件:●XilinxVivado/Linux系统/Python语言05作品评分细则●所有最终提交的作品将由DIGILENT工程师依据以下评分项综合打分评选出最终的名次:1)作品创意20’2)作品完成度30’3)作品实现难度20’4)作品提交内容的完整度30‘5)额外加分项:使用Zedboard,Zybo,Arty-Z7参与活动,额外+10'3推荐阅读资料推荐阅读社区多篇热门Python阅读集结:1《项目教程|手把手教你如何在Zybo上跑Python制作一个LED呼吸灯》2《资源分享|基于Python的开源人脸识别库》3《学习笔记|PythonImage库(PIL)常用操作函数》4《知乎问答|你们都是怎么学Python的?》5《话题讨论|Python为何能坐稳AI时代头牌语言》6《机器学习|Zynq+PYNQ+Python:在PYNQ-Z1上搭建二值神经网络(BNN)》活动参与:1)www.digilent.com.cn/makerhubs/ython-on-everything.html2)申请加入部落3)9月8日前提交完成作品想要申请开发板租借,参与此次活动的童鞋(限在校学生),请在本帖内留言哟~~
    发布于 08-08
  • 工科街(求职招聘区)

    一条纯粹属于在校工科生的话题街。尽情释放内心的小怪兽,海侃校园内外,闲聊天南地北

    发帖数

    51
    招聘 | 小米南京招聘Linux/Android工程师(2017.12.11发布)
    招聘单位:招聘岗位:1.负责Android系统性能优化2.从Linuxkernel/AndroidFramework层面监控及持续性优化职位要求:1.熟悉C/C++和Java其中一项语言2.了解Android系统架构3.了解Linux内核的内存管理,对调度、内存、存储的子系统有一定理解4.有实际的Linux或Android性能优化经验者优先5.责任心强,有优秀的团队合作和沟通能力工作地点:南京市雨花台区楚翘城联系方式:liucai@xiaomi.com
    发布于 12-11

干货热帖

  • 涂鸦+代码教你如何构建一个简单的最小神经网络
    闲来无事,想尝试做一个简单的最小神经网络,通过训练来让其识别一些东西。在这篇文章里,我将试着通过结合涂鸦与代码的方式来更为直观地向大家解释这一最小神经网络的构建过程。好了,让我们开始吧!01很多神经网络的术语都是从生物学的角度出发并赋予其意义的,所以让我们从最顶层的一番小科普开始:大脑是十分复杂的,但总的来说可以将之分为几个基本的运作部分:刺激-输入-处理-输出当然,刺激也可以通过内在产生(如感知或想法):我们来看一下基本的、简化的大脑构造。下图右侧为一个大脑的横切面,其中四周灰色的部分为神经元层,白色的部分为轴突:大脑令人惊讶之处其实就是“布线”神经元是大脑计算的基本单位,它接收和整合来自其它神经元的化学信号。取决于多种因素,它要么什么都不做,要么产生电信号或动作电位,其反过来通过触发信号通知其它相连接的神经元:做梦,记忆,想法,自我调节运动,反射以及你所想所做的一切都是通过这个过程产生的:数以百万计甚至数十亿的神经元以不同的速率发射并建立连接,从而产生不同的并行运行子系统,并基于此构建了一个生物意义上的神经网络。当然,上述是一种泛化和简化的解释。但现在我们可以描述一个最小的生物神经网络是什么了,以手指被图钉扎到而产生应激反应为例:皮肤被图钉扎到-感觉神经元-中间神经元-运动神经元-肌肉产生应激反应:用图形的方式可以正式地描述为:为了在当前这一阶段尽可能解释地简单,圆圈代表神经元,它们之间存在连接,连接线表示信息从左到右的向前移动。第一个神经元目前正在发射,在此通过阴影来指代。它会被赋予一个数字(当它正在发射时为1,否则为0)。神经元之间的数字表示连接权重。如果说上一张图代表了神经网络的一个时刻,而对神经网络更准确的描述将被分成时间段:02在构建神经网络之前,我们需要了解权重是如何影响神经元以及神经元是如何学习的。让我们从一只兔子(一只真实的实验兔子)和一个经典的调节实验来说起:当受到无害的吹气时,像人类一样兔子通常会眨眼:我们可以用一个简单的图表来建模这个行为:就像之前的图表一样,上图显示的只是当兔子感应到空气的那一刻,在此我们将它编码为一个布尔值。在此基础上,现在我们计算第二个神经元是否基于权重值进行触发,如果权重为1,感觉神经元正在触发我们眨眼,如果低于1,则不眨眼。换句话说,我们的第二个神经元有一个阈值1。让我们来引入另一个元素,当兔子接收到一个无害的听觉声音:我们可以用以下方式模拟兔子缺乏兴趣:可以看出,唯一不同的是权重现在是0,所以兔子不会有眨眼,至少现在还没有。那么现在让我们训练我们的兔子根据混合刺激命令来眨眼(混合听觉声音与吹气):重要的一点是,每个事件都发生在不同的时间点,因此图表看起来会是这样:声音并没有产生任何影响,但是吹气仍然会引起兔子眨眼的反应,这里要注意的要点是我们通过权重乘以刺激(上图中红色)来表示这一点。到这里,我们可以将在一串复杂行为中的“学习”,简化定义为神经网络中连接的神经元之间时间权重的递增变化。为了训练我们的兔子,我们必须得重复这个过程:下图对应的是初始状态和前3次实验:请注意,在每次实验之后,声音的权重会增加(红色),这个数字在这一点上是任意的-我选择了0.30,但它可以是任何数字,甚至是负数。直到第三次实验,兔子都有着相同的行为。但是在第四次实验之后,一些新的事情发生了......我们发现了新的行为。这次实验中,我们暂停了吹气,但兔子在听到声音后仍然眨了眼睛!对这一新行为的解释如下图:也就是说,现在我们的兔子已经被训练出可以在听到声音后就眨眼了。注:真实实验中,通过在几个星期或更长时间内进行大约60次实验即可引起兔子的上述反应03好了,现在让我们离开大脑和兔子的“生物世界”,而是将上述我们已经学到的一些知识应用于人工神经网络的构建。我们要做的第一件事是去尝试定义一个简单的问题。假设有一个4个按键的机器,如果你按下正确的按键则会给你提供食物。为此,目标对象需要学习去按哪个按键才能够获取食物:我们可以通过以下图形方式来表示按下按键:这一问题很容易在整体上理解,所以让我们看看所有可能的结果:现实中,按下按键3就能获得食物为了用代码创建一个神经网络,我们首先需要一个模型或图形来匹配它。对于目前的这一问题,我们可以用下图来对其生物表象进行松散地模拟:这一神经网络所做的可以简单理解为接收一个输入(在此例中即为感知哪个按键被按下),然后通过权重修改上述输入,最后根据所添加的图层返回输出。这听起来可能有点复杂,那么就让我们来看看我们的模型是如何来表示按钮被按下的:注意所有权重都是零,所以这一神经网络处于空白状态,但是其完全连接,就像新生儿一样因此,我们将外部事件映射到神经网络输入层并计算输出,这个输出可能符合也可能不符合实际结果(此处即,能“吃鸡”的正确按钮)。但现在我们先忽略这一点,并开始用计算机友好的方式来编写这个问题的代码。04让我们从输入和权重开始(这里我将使用Javascrit):varinuts=[0,1,0,0];varweights=[0,0,0,0];//wecancallthesevectorsforconvenience.下一步是创建一个函数,它接收这些输入和权重并计算输出;会是这样一个功能:functionevaluateNeuralNetwork(inutVector,weightVector){varresult=0;inutVector.forEach(function(inutValue,weightIndex){layerValue=inutValue*weightVector[weightIndex];result+=layerValue;});return(result.toFixed(2));}//Mightlookcomlex,butallitdoesismultilyweight/inutairsand正如所料,如果我们运行上述代码,我们会得到与我们上图模型相同的结果...evaluateNeuralNetwork(inuts,weights);//0.00代码实例可参考:htts://codeen.io/k3no/en/GWyJgP下一步对我们神经网络的升级则是让其将自己的输出结果与真实情况进行比对。让我们先把这个特定的真实情况编码成一个变量:为了检测是否不匹配(以及有多少不匹配),我们将添加一个错误函数:Error=Reality-NeuralNetOutut有了这两个部分之后,我们现在可以来判断我们的神经网络了,比对结果错误如下图:以及更为重要的,比对结果正确图(可以吃鸡):到这里,现在我们可以明确知道我们的神经网络模型在何种情况下输出的结果会不work(并且在数值上会差多少),这很好!很好的原因是因为现在我们可以使用错误的反馈结果来指导我们的学习。这里,如果我们对我们的“错误函数”做一些小的改变,会让这一切显得更有意义,如下所示:Error=DesiredOutut-NeuralNetOutut这一微小但重要的改变在这里可以默认理解为:我们将使用以前观察到的结果与未来的表现来进行比对(换句话说,与“学习”结果进行比对,后面很快会讲到)。这一逻辑同样适用于现实生活,因为真理(正确的结果)往往是会重复显现的。所以,我们可以将上述策略理解为一种自我进化策略。理解了以上逻辑之后,下面对于示例代码的修改就变得简单了,我们只需要添加一个新变量:Error=varinut=[0,0,1,0];varweights=[0,0,0,0];vardesiredResult=1;以及新的函数:functionevaluateNeuralNetError(desired,actual){return(desired—actual);}//AfterevaluatingboththeNetworkandtheErrorwewouldget://"NeuralNetoutut:0.00Error:1"代码实例可参考:htts://codeen.io/k3no/en/dvaGX好了,到这里,对于我们之前的讲解做一下友情回顾:我们从定义一个问题开始,然后针对其以神经元生物网络的形式建立一个简单的模型。接着,我们将这一模型的输出结果与真实结果/期望结果做比对,并通过某种方式来修正错误的比对结果。这一过程对于计算机和人类来说即为学习。05那么如何来训练一个神经网络呢?无论是对于生物神经网络还是人工智能来说,“学习”的基本原则都可以理解为基于重复实验与学习算法。对于这两个关键词,我们来一一解决。让我们先从学习算法开始。本质上,学习算法可以理解为在一次经历之后神经元的物理和化学特性所发生的变化:在代码和我们的模型中,学习算法可以简单理解为我们将随着时间的推移而改变某些东西。秉承着简单易懂的原则,让我们先添加一个变量:varlearningRate=0.20;//biggerrate,biggerfasterlearnings:)我们将改变什么?与之前兔子的例子一样,我们将改变权重,特别是我们想要的结果的权重:如何对这样一个算法进行编程不同人会有不同的选择。为简单起见,我只是增加了学习速度的权重,在这里它是一个函数:functionlearn(inutVector,weightVector){weightVector.forEach(function(weight,index,weights){if(inutVector[index]>0){weights[index]=weight+learningRate;}});}使用这个学习函数,在每个学习周期(或实验)前后,都会将我们的学习速率添加到活动神经元的权重向量中,其结果如下://Originalweightvector:[0,0,0,0]//NeuralNetoutut:0.00Error:1learn(inut,weights);//NewWeightvector:[0,0.20,0,0]//NeuralNetoutut:0.20Error:0.8//Ifitisnotaarentlyobvious,aNeuralNetoututcloserto1//(chickendinner)iswhatwewant,soweareheadingintheright//direction代码实例可参考:htt://codeen.io/k3no/en/qrJoXO好了,我们正朝着正确的方向前进,现在我们需要做的最后一步就是重复实验。这不难,本质上我们只是去一遍又一遍地做一些事情,而在代码中我们只是指定了实验的次数:vartrials=6;并根据我们所定义的实验次数,将我们的学习函数应用于我们的神经网络中,即这一训练函数为:functiontrain(trials){for(i=0;i<trials;i++){neuralNetResult=evaluateNeuralNetwork(inut,weights);learn(inut,weights);}}我们的最终读数为:NeuralNetoutut:0.00Error:1.00WeightVector:[0,0,0,0]NeuralNetoutut:0.20Error:0.80WeightVector:[0,0,0.2,0]NeuralNetoutut:0.40Error:0.60WeightVector:[0,0,0.4,0]NeuralNetoutut:0.60Error:0.40WeightVector:[0,0,0.6,0]NeuralNetoutut:0.80Error:0.20WeightVector:[0,0,0.8,0]NeuralNetoutut:1.00Error:0.00WeightVector:[0,0,1,0]//ChickenDinner!代码实例可参考:htts://codeen.io/k3no/en/dvBZLe?editors=0012我们现在得到一个权重向量,只有当输入向量与真实结果(第三个按钮向下)一致时,才会导致输出结果1(吃鸡)的产生。06我们刚刚创建的这个东西能带给我们什么?在这一特定的案例中,我们的神经网络(在被训练之后)可以识别或区分输入之间的差异,并告诉你哪一个输入会产生一个所希望的输出结果(当然,我们仍需要为特定的情况进行编程):除此之外,我们得到了一个比例模型,玩具或者说是学习工具,可以让我们进一步了解机器学习,神经网络和人工智能。EECS圈新工科不只是口号欢迎勾搭
    亮了(0) 20 0 前天 16:42
  • 教程 | 以Arty A7为例,教你如何从Flash启动MicroBlaze软核
    在诸多关于MicroBlaze软核处理器的例程中,往往都是使用JTAG下载然后借助SDK执行程序代码。然而无论是在项目展示还是实际应用中,我们都希望我们的设计可以即插即用,免去重复烧写的麻烦和必须使用SDK运行程序的限制。事实上,为了部署一个真实的系统,需要在没有任何人为操作的情况下从非易失性存储器中启动MicroBlaze处理器并加载程序代码。本篇教程,我们就围绕这个话题,以DigilentArtyArtix-7开发板为例,教你如何在板载的QSPIFlash中存储比特流配置文件和应用程序。QSPI有两个主要作用:●配置ArtixFPGA●存储应用软件对于第一个功能,我们在Vivado设计中不需要包含QSPI接口。我们只需要在Vivado配置中更新对QSPI的设置,提供QSPIFlash存储器与FPGA配置管脚的连接。然而,一旦FPGA配置完成并调用MicroBlaze软核处理器,我们则需要在设计中引入与QSPIFlash通信的接口。这个新添加的接口允许引导程序(bootloader)从QSPIFlash存储器中复制应用程序到Arty实际执行的DDRSDRAM存储介质中。当然,这会引起一个问题,即MicroBlazebootloader(引导程序)从何而来?开发bootloader(引导程序)的流程图如下所示:我们的目标是创建一个MCS镜像,它包含了FPGA比特流和应用软件文件,我们要将它烧写到QSPIFlash中。为了实现这个方案我们需要在Vivado和SDK中执行以下步骤:●在已经存在的VivadoMicroBlaze设计中引入(添加)一个QSPI接口。●在Vivado中编辑器件设置,使用MasterSPI_4来配置器件,并且将bit文件压缩,构建完成后将应用导出到SDK。●在SDK中,基于导出的硬件设计创建一个新的应用工程。在工程创建对话框,选择SRECSPIBootloader模板。这个选择会创建一个SRECbootloader应用,它会从QSPIFlash中加载主应用程序代码。在构建bootloaderELF之前,我们首先要为应用软件定义对于QSPI基址的地址偏移,在这个示例中为0x600000。我们在blconfig.h中定义这个偏移量。我们还需要更新SRECBootloaderBSP来鉴别正确的串口Flash存储器件。因此重新配置BSP。使用的系列标识号在BSPlibsrc目录下的xilisf.h中定义。对于这个应用我们选择类型5,因为Arty板卡使用MicronQSPI器件,它的标识号即为类型5。●现在我们在SDK中创建第二个应用工程。这也是我们将使用bootloader加载的应用程序。在这个应用中我们创建了一个简单的“helloworld”工程,确保在linker文件中这个程序从DDRSDRAM开始运行。为了创建MCS文件,我们需要应用程序为S-record格式。这个格式以ASCII格式存储二进制信息。(这个格式已经有40年的历史,最初是为8位Motorola6800微处理器而开发的。)我们可以使用SDK将生成的ELF转换为S-record格式。为了在SDK中生成S-record文件,我们打开bashshell窗口,切换到ELF所在的目录然后输入如下命令:cmd/cmb-objcoy-Osrec<a>.elf<a>.srec●创建好bootloaderELF文件后,现在我们要在Vivado内将比特流(bitstream)文件与bootloaderELF文件合并。这个步骤允许bootloader被加载到MicroBlaze处理器的本地存储空间,并且按照配置运行。因为这个存储空间很小,所以bootloader应用也需要很小才可以。如果你正遇到减小软件应用大小的问题,不妨在增加本地存储内存之前考虑使用编译器优化。●创建好bit文件和S-record文件后,我们使用Vivado硬件管理器来增加配置存储器。●最后一步是生成统一的MCS文件,包含合并的bitstream(比特流)文件和应用软件。当生成这个文件时,我们需要记住加载应用程序时使用与SRECbootloader相同的偏移量。一旦这个文件构建完成并烧写到QSPI存储中,我们就可以进行测试查看MCS文件的工作情况。将Arty板卡与PC终端建立连接然后按下板卡上的复位(reset)按钮。几秒钟后你就会看到Arty板卡上的“done”LED灯亮起,然后在终端窗口中看到SRECbootloader的执行结果。报告应该显示S-record文件在程序执行前已经从QSPI加载到DDRSDRAM中了。到这里,我们就有了一个可以部署到我们设计中的MicroBlaze工作系统了。
    亮了(0) 45 0 前天 11:24
  • Zedboard安装与移植OpenCV
    本文首发于:CSDN博客作者:w371500241主要分为两个大部分,OenCV在PCUbuntu上的安装和OenCV在Zedboard上的移植。一、OenCV在PCUbuntu上的安装采用的是Ubuntu14.04系统,在OenCV官网下载的源码版本为2.3.11.安装第三方库获取su权限进行操作。安装第三方库,命令如下:at-getinstallbuild-essentialat-getinstallcmakecmake-guiat-getinstalllibgtk2.0-devat-getinstalllibavcodec-devlibavformat-devlibswscale-devat-getinstalllibdc1394-22-devat-getinstalllibjeg-devlibng-devlibtiff-devlibjaser-dev2.新建安装文件夹将OenCV解压到自建目录/home/linux/OenCV-2.3.1下,新建目标build。这是个临时文件夹,安装完成后可以删除。进入build目录。进行命令配置:mkdirbuildcdbuildcmake-DCMAKE_BUILD_TYPE=RELEASE-DCMAKE_INSTALL_PREFIX=/usr/local../在这里设置了安装目录为/usr/local(其实也是默认的安装路径,当然可以修改为自定义路径),命令完成后build目录下多了一些文件,可以通过ls命令进行查看。3.OenCV安装配置执行ccmake./进行OenCV配置,把WITH_1394,WITH_CUDA,WITH_FFMPEG设置为OFF,其他不变;按c键进行配置,g键产生Makefile。4.进行编译和安装:这个过程时间比较长,make比较占时间。makemakeinstall安装结束后可以在/usr/local/lib目录下看到OenCV的链接库。5.配置系统变量vi/etc/ld.so.conf.d/oencv.conf添加/usr/local/lib,保存并退出,进行配置:sudoldconfig打开并修改bash.bashrc文件:vi/etc/bash.bashrc在末尾添加如下两行:PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/kgconfigexortPKG_CONFIG_PATH保存并重启终端。6.测试OenCV的效果进入OenCV的解压目录,找到samles文件夹,运行其中的C程序样例进行测试cd/home/linux/OenCV-2.3.1/samles/cchmod+xbuild_all.sh./build_all.sh./facedetectlena.jg测试效果如图所示:二、OenCV在Zedboard上的移植前提是Ubuntu要配置好交叉编译环境,也需要获取su权限1.新建安装文件目录新建文件夹OenCV_zed,作为OenCV移植Zedboard的相关文件的配置文件夹;将OenCV源码解压;此时的目录/home/linux/OenCV_zed/OenCV-2.3.1;2.配置安装链在OenCV-2.3.1文件夹内建立install和build文件夹,并创建toolchain.cmake文件,其内容如下:set(CMAKE_SYSTEM_NAMELinux)set(CMAKE_SYSTEM_PROCESSORarm)set(CMAKE_C_COMPILERarm-xilinx-linux-gnueabi-gcc)set(CMAKE_CXX_COMPILERarm-xilinx-linux-gnueabi-g++)3.OenCV安装配置进入bulid文件夹进行命令配置,关联toolchain.cmake文件并配置移植OenCV的安装目录:cmake-DCMAKE_TOOLCHAIN_FILE=toolchain.cmake-DCMAKE_INSTALL_PREFIX=/home/linux/OenCV_zed/OenCV-2.3.1/install../4.生成Makefile文件执行ccmake./进行OenCV配置,将所有WITH开头的选项选成OFF(除了WITH_V4L为ON);按c键进行配置,g键产生Makefile5.编译安装通过make编译,makeinstall进行安装;安装结束后Zedboard上的OenCV库已经生成,在install文件夹下。6.OenCV库移植可以通过将OenCV运行库压缩到ramdisk镜像中的方法进行移植;不过在这里将OenCV运行库压缩成镜像,Zedboard上板测试时通过加载镜像的方式使用;下面进行镜像制作:cd/home/linux/OenCV_zed///生成镜像的目录ddif=/dev/zeroof=oencv_lib.imgbs=1Mcount=80//镜像的名字oencv_lib.img和大小80M,可以根据实际链接库的大小进行设置mkfs.ext2-Foencv_lib.imgchmodgo+woencv_lib.imgmountoencv_lib.img-oloo/mntc/home/linux/OenCV_zed/OenCV-2.3.1/install/*/mnt//复制相应的库的即将压缩的镜像中chmodgo-woencv_lib.imgumount/mnt在相应的/home/linux/OenCV_zed/目录下就会生成oencv_lib.img镜像文件,可以在Zedboard上加载使用。7.移植结果测试测试的源码为《嵌入式系统软硬件协同设计实战指南》书上的edge_detection.c,如下:#include"cv.h"#include"highgui.h"IlImage*doCanny(IlImage*in,doublelowThresh,doublehighThresh,doubleaerture){if(in->nChannels!=1)return0;//CannyonlyhandlesgrayscaleimagesIlImage*out=cvCreateImage(cvGetSize(in),in->deth,//IPL_DEPTH_8U,1);cvCanny(in,out,lowThresh,highThresh,aerture);return(out);};intmain(intargc,char**argv){if(argc!=3)rintf("argumentserror!formatorigin_image.bmtarget_image.bm\n");IlImage*img_rgb=cvLoadImage(argv[1]);IlImage*img_gry=cvCreateImage(cvSize(img_rgb->width,img_rgb->height),img_rgb->deth,1);cvCvtColor(img_rgb,img_gry,CV_BGR2GRAY);//cvNamedWindow("ExamleGray",CV_WINDOW_AUTOSIZE);//cvNamedWindow("ExamleCanny",CV_WINDOW_AUTOSIZE);//cvShowImage("ExamleGray",img_gry);IlImage*img_cny=doCanny(img_gry,10,100,3);if(cvSaveImage(argv[2],img_cny,0)!=0)rintf("SaveImageSuccessful\n");//cvShowImage("ExamleCanny",img_cny);//cvWaitKey(0);cvReleaseImage(&am;img_rgb);cvReleaseImage(&am;img_gry);cvReleaseImage(&am;img_cny);//cvDestroyWindow("ExamleGray");//cvDestroyWindow("ExamleCanny");return0;}对edge_detection.c进行交叉编译,命令如下arm-xilinx-linux-gnueabi-g++-I/home/linux/OenCV_zed/OenCV-2.3.1/install/include-I/home/linux/OenCV_zed/OenCV-2.3.1/install/include/oencv-L/home/linux/OenCV_zed/OenCV-2.3.1/install//lib-loencv_core-loencv_imgroc-loencv_highgui-loencv_ml-loencv_video-loencv_features2d-loencv_calib3d-loencv_objdetect-loencv_contrib-loencv_legacy-loencv_flann./edge_detection.c-o./edge_detection.o生成可执行文件edge_detection.o;将OenCV库文件oencv_lib.img、可执行文件edge_detection.o和原图像lena.bm放入U盘中,启动Zedboard,挂载U盘:mount/dev/sda1/mnt将镜像文件oencv_lib.img挂载到/usr/lib文件夹中:cd/usrmkdirlibmount/mnt/oencv_lib.img/usr/lib查看挂载结果,如图所示:运行可执行文件./edge_detection.olena.bmout.bm,如果出现successful则编译成功,如图所示:边缘检测的结果保存在输出图像out.bm中。不能挂载U盘的仿zedboard板子(俺的就是),可以采用以下流程将板子自带的4G的SD卡格式化成fat32格式,将edge_detection.o和lena.bm(使用jg格式会出错)以及oencv_lib.img和官网的OOB文件全部拷到SD卡中,将zedboard板跳帽设置成从SD卡启动,上电后挂载SD卡:在超级终端中输入fdisk-l可知SD卡为/dev/mmcblk01,然后挂载:mount/dev/mmcblk01/mnt/SD卡挂载完成后,进入/mnt可看到SD卡里面的文件,将oencv_lib.img挂载到/usr/lib(板子如果没有lib可建立该目录)mount/mnt/oencv_lib.img/usr/lib在超级终端中进入SD卡挂载的目录/mnt,然后执行./edge_detection.o./lena.bm./lena_edge.bm即可得到边缘检测后的图片lena_edge.bm,最后将lena_edge.bm拷贝到电脑上看效果。
    亮了(0) 36 0 12-13
  • 手把手教你为Cmod A7构建MicroBlaze软核zt
    作者:白小白_3003415首发于:爱板网FPGA即现场可编程门阵列,属于可编程逻辑器件的一种。随着工艺的进步和EDA设计工具的不断发展,FPGA的门槛(学习成本和价格成本)也越来越低,目前已经成为实现数字系统的主流平台之一。尤其是很多厂商都在开发便携式、低成本的拇指型最小系统式开发平台,好用不贵,让越来越多学生/工程师进入到可编程逻辑的世界中来。而今天爱板网要给大家推荐一款拇指型FPGA开发平台,基于全球最大的FPGA厂商Xilinx的开发平台,板子为CmodA7,由Digilent设计制造。在CmodA7板子上,有44个可以作为数字FPGAI/O的引脚,用户能够非常方便地将可编程逻辑设计直连面包板电路,同时板载USB-JTAG编程电路/USB-UART桥接功能,配合XilinxVivado开发工具,可以进行各类数字逻辑电路以及MicroBlaze嵌入式软核处理设计。CMODA7开发板特性:htt://www.digilent.com.cn/roducts/roduct-cmod-a7-35t-breadboardable-artix-7-fga-module.html·XilinxARTIX-735TFPGA·512KBSRAM,支持8位总线以及8毫微秒访问时间·4MBQuad-SPIFlash·USB-JTAG编程电路/USB-UART桥接·USB或外部3.3-5.5V连接DIPins供电·2个LED、1个RGBLED、2个按钮·48引脚DIP连接器,带有44个数字I/O以及2个模拟输入(0-3.3V)·1个Pmod连接器,带有8个数字I/O本文中的CMODA7开发板搭载的FPGA具体型号为ARTIX-735Tcg236-1,这是XilinxARTIX-7系列中中端的FPGA产品。Artix-7系列是Xilinx28nm的FPGA数字开发平台,实现了低成本和低功耗,并且经过优化,可以在设计中实现最佳的性能与功耗结合,另外,Artix-7器件具有非常显著的特点,集成了AMS、收发器等功能,可以广泛的应用在软件定义无线电、机器视觉照相以及低端无线回传的领域。上电使用CMODA7开发板使用非常简单方便,一根micro-USB线就能搞定一切,同时可用于供电、下载调试、USB-UART功能,方便工程师开发。板卡通过MicroUSB接口供电口上电后,可以看到会提示需要安装板载的USB转串口芯片驱动,这款芯片是FTDIF2232系列,非常常见,可能很多工程师的电脑上本身就有这个芯片的驱动,再不然,我们也可以在网上找到驱动,安装后可以看到相应的串口。波特率设置为9600,8bits,noarity,1stobit,复位板卡即能看到串口输出,板子默认程序是一个Memory的测试程序,会输出测试结果,Memory正常工作的测试结果如下。另外,通过CMODA7板子上另一个按键可以实现RGBLED的色彩变换。开发环境CMODA7FPGA开发板可以选用Xilinx官方的EDA设计工具Vivado,最新版本是2017年的,这是一个非常强大的工具,但是有些遗憾的是,要使用其全部的功能,是需要Lincence的,而且完整的安装包也异常的大,20GB多的容量有些吓人。不过目前官方也推出了网页安装包,用这个非常方便,可以最精简的选择你所需要的器件,安装程序的话可以去官网下载。本文使用的是Vivado2016.3的版本,曾经下载过的,安装包太大,懒的下载最新的。有一点需要注意的,在安装过程中可以一并选择安装SDK软件。最精简的安装方式也要20GB的空间。整个安装过程大概45分钟左右,当然,这个安装时间是依赖你所用的计算机性能。开发工具安装准备完毕后,下面将使用VivadoIPIntegrator在CMODA7开发板上构建MicroBlaze软核,并实现相应的功能,比如MicroBlaze软核实现串口输出。下载安装CMODA7的板级支持包下载地址:htts://reference.digilentinc.com/vivado/boardfiles2015将CMODA7-35T开发板的板级支持包文件复制到Vivado的安装目录下X:\Xilinx\Vivado\2016.3\data\boards\board_files创建项目打开VivadoEDA工具,熟悉的界面。新建一个名为hello_eeboard的项目名选择RTLProject,其它默认,不同勾选,一直点Next下一步。选择对应的板卡CmodA7-35T最后会有一个项目的信息以及器件的信息的总的概览,也就是你前面设置的一些信息,确认无误后点击完成就可以进入到EDA工具的主窗口。在项目中创建新的Block设计下图则是hello_eeboard项目的主窗口界面,在这里我们就可以基于Block设计创建MicroBlazeIP或者添加RTL,整个主窗口界面的左侧有不少导航栏,包括了创建硬件设计、仿真、综合、生成bit文件等功能。这里的话我们通过IPintegrator创建一个新的Block设计。添加MicroBlaze软核&am;配置在创建的Block设计中,在Diagram框中点击addIP添加MicroBlaze软核(双击就可实现添加)在Block设计的Board标签中找到系统时钟(systemclock)添加(直接拖动到Diagram即可完成添加),board标签下的东西就是之前安装的CMODA7-35T的板级文件。点击RunBlockAutomation,打开MicroBlaze软核的BlockAutomation界面这个界面中你可以选择配置多少memory到你的软核,这里的设置如下完成后会自动执行BlockAutomation动作,会按照你刚刚的设置自动生成一系列IPBlocks,如下图所示,另外现在不要执行RunConnectionAutomation动作,因为我们还要继续配置。添加CellRAM单元还是在Board标签栏中找到CellRAM,直接点击拖动到Diagram框中这里我们需要做的是将rdclkin连接到clk_out1上添加外设单元在hello_eeboard项目一开始就打算做一个基于MicroBlaze软核的串口输出,所以在软核添加完毕后我们还需要添加UART外设,同样在board标签中找到USBUART单元拖动到Diagram中。所有外设单元都添加完毕,我们可以选择RunConnectionAutomation。确保RunConnectionAutomation框中所有的AllAutomation都已经勾选。点击完成会为BlockMemory以及外设单元创建AXI总线连接,然后我们可以点击左侧中的RegenerateLayout来重新排版你的框图,使之看起来更具有流程化,更好看了。验证设计以及创建HDLWraer点击Tools-->ValidateDesign,它会检查设计、连接是否有错。验证设计结果无误验证无误之后我们可以创建HDLWraer,点击BlockDesign框中的Sources标签,找打自己的设计项目文件-->createHDLWraer在弹出的窗口中选择LetVivadomanagewraerandauto-udate,然后点击OK。这个过程会在VHDL中创建一个允许你生成bitstream文件的Tomodule。生成Bit文件上一步完成之后,我们就可以先保存下你的项目,然后在Flow-->GenerateBitstream生成bit文件这个过程中会执行SynthesisandImlementation,根据你的计算机性能所花费的时间有所不同,笔者的渣渣笔记本将近用了半个多小时。bit文件生成后会出现如下的弹窗,也就是说,到这边我们的MicroBlaze的软核正式构建完成了,就差把它配置到FPGA中,这里先不用管它,点击Cancel。按照一开始的想法,我们要用软核实现串口的功能,所以还要写个小程序用起来。导出硬件到SDK嵌入式的程序需要用到C/C++编辑器,这里将使用Xilinx内置的VivadoSDK,基于eclise。点击File-->Exort-->ExortHardware这弹出窗口中勾选IncludeBitstream,这里输出的作为VivadoSDK所需的系统打包的硬件。这时同样会有两个文件被创建.sysdef以及.hdf(.hdf包括了硬件设计规格以及IPBlocks),控制台会显示详细的信息,如下所示,这是创建SDKWorksace必须的,不用在意。然后在VivadoEDA主窗口中打开XilinxSDK,Files-->LaunchSDK这时在弹出的窗口中选择默认的路径设置LocaltoProject点击OK就会打开XilinxSDK以及导入你的硬件信息。XilinxSDK算是作为一个独立的C/C++软件开发工具,可以独立于Vivado使用。这里的话,我们就可以基于我们之前构建的硬件平台(MicroBlaze软核)上做嵌入式的开发。在XilinxSDK中创建你的项目按照最初的想法,在MicroBlaze上做一个串口输出的hello_eeboard程序,点击File->new->AlicationProject,在SDK中创建hello_eeboard项目名,C语言开发方式。看到有相应的模板,那就不客气,直接拿来改下。载入模板后可以看到有几部分的内容,dislay_hello_world包含了所有的binaries,.C以及.H(Header)文件;dislay_hello_world_bs也就是板子支持的文件夹;这里我们主要的工作目录为dislay_hello_world文件夹,点击里面的helloworld.c文本。helloeeboard程序#include<stdio.h>#include"latform.h"#include"xil_rintf.h"intmain(){init_latform();rint("HelloEEboard\n\r");cleanu_latform();return0;}到这里基本上一切都就绪了,就差东风了。将bit文件下载到FPGA中首先确保CMODA7-35T开发板已经连接到电脑,USB-JTAG、USB-UART都可以正常工作。点击SDK中的ProgramFPGA按钮,如下图所示点击Program,将你的硬件设计下载到你的FPGA中也就是将你构建的MicroBlaze配置到FPGA中将程序下载到Microblaze软核中在FPGA中配置完MicroBlaze软核,接下来就可以将hello_eeboard程序下载到MicroBlaze中,选中hello_eeboard项目,选中RunAs-->LaunchonHardware(SystemDebugger)程序下载中下载完成后,我们可以打开串口终端,CMODA7开发板上的复位键可以看到串口成功输出“HelloEEboard”的结果,到这里,MicroBlaze软件的构建以及在软核上实现编程都完成了。其实吧,只要一旦软核构建完成,你就可以在此基础上进行各种嵌入式的开发,到这步的话已经跟普通的微控制器编程开发区别不大了,而使用FPGA的好处在于如果你想改变硬件的话,还可以通过VivadoEDA工具构建不同功能的软核配置不同的外设功能,当然,这样做的话还是需要退回到VivadoEDA工具上修改,然后保存,重新导出新的硬件规格到SDK中进行开发,但是,这相比单一的嵌入式微控制器的开发,在FPGA上软核的构建方式无疑更自由,兼容度更广,好处是显而易见的。当然,凡事都讲两面,说完了利,也该说说弊,对于如果仅仅想做嵌入式开发,选择一个合适的单片机明显更为合适,毕竟开发难易度、成本、效能都摆在那了。而如果要选择使用FPGA的话,要么是本身就有学习或者使用FPGA的打算,要么无疑是想向更高难度,更灵活自由,以及那些嵌入式微控制器没法涉及的领域挑战,因为在那里FPGA有绝对的优势,比如说现在很火的人工智能、4K/8K视频解码等一些需要大规模并行计算的高级应用,当然,现在在精而美的移动产品中也有不少小封装的FPGA存在,一句话来总结就是,依托于成本和门槛的降低,目前FPGA的应用已经越来越广了,此时不学FPGA,更待何时。
    亮了(0) 33 0 12-13
  • 在Nexys4 DDR上实现的DDR2读写例程
    本文使用Vivado2015.4在DigilentNexys4DDR(以下简称N4DDR)开发板上实现DDR的读写。FPGA如果需要对DDR进行读写,则需要一个DDR的控制器。根据官方的文档(UG586,下载链接在文末),DDR控制器的时序主要有三:(1)首先是控制信号,如下图:从上图可以看出,只有当a_rdy信号有效时,程序所发出的读写命令才会被控制器接收。这点必须注意。(2)然后是写操作时序,如下图:由图可知,在向DDR写数据时,需要提供写命令a_cmd、地址a_addr、数据a_wdf_data等信号,且写入的数据最多可以比a_cmd提前一个时钟周期有效,最迟可以比a_cmd晚两个时钟周期有效。【特别注意】在写数据的时候必须检测a_rdy和a_wdf_rdy信号是否同时有效,否则写入命令无法成功写入到DDR控制器的命令FIFO中,从而导致写操作失败。(3)最后是读操作时序,如下图所示:读操作的时序比较简单,只需要注意a_rdy是否有效即可,其余不再赘述。Xilinx在Vivado中提供的MemoryInterfaceGenerator的IP核就是我们需要的DDR控制器,如下图所示。这里我们可以直接双击上面的MIG的IP核,开始例化我们所需的DDR控制器。(此时Win7以后的Windows版本(不含Win7)打开此IP核会报错,解决方法见htt://blog.csdn.net/qq_20091945/article/details/53862467)打开后是如下图所示的界面,点Next。给模块起个名字,根据实际情况选择控制器数量(这里笔者选择1),继续Next,如下图所示。在开发板芯片型号所对应的方框前打勾,如下图所示。根据开发板上的DDR芯片选择DDR的种类,如N4DDR的开发板上的DDR芯片是DDR2的,因此如下图选择。然后在ClockPeriod中输入合适的时钟周期长度(N4DDR的官方文档建议DDR的时钟为325MHz,故此处填3077s);接着在MemoryPart中选择开发板上的DDR芯片的具体型号(N4DDR官方文档上说明为MT47H64M16HR-25E);然后输入DataWidth,此处以16为例。如下图所示。选择InutClockPeriod,这里填开发板的系统时钟(N4DDR为100MHz)。根据应用需要选择地址映射方式(这里保持默认的Bank-Row-Column)。然后,这里的SystemClock、ReferenceClock建议选择NoBuffer,SystemResetPolarity则根据应用需要灵活选择(这里设置为低电平有效),如下图所示。InternalTerminationImedence的选取应当参考开发板的官方文档说明,这里选50欧姆即可,继续Next。选择FixedPinOut。接下来是DDR芯片的引脚分配。官网应该能找到,这里直接给出。文末会给出与此对应的引脚约束文件(n4ddr_ddr2_io_assign.ucf)。耐心填完之后点击Validate按钮,没有错误的话会弹出一个对话框提示“CurrentPinoutisvalid.”然后的3个信号建议选择Noconnect,后面由我们自己根据需要连接到板上的相应引脚。后面一直Next下去,点Accet,然后就可以点击Generate了。后面会再弹出一个对话框,直接点默认选中的按钮即可。好了,下面是笔者自己编写的测试DDR2读写的程序。文末将提供对应工程的下载链接。//*****************************************************************************//Author:Z.M.J.@CSE,SEU//Alication:MIGv2.4//Filename:examle_to.v//DateCreated:FriDec302016////Device:7Series(Nexys4DDR)//DesignName:DDR2SDRAM//Purose:AdemoofDDR2'sreadandwrite//Reference:ug586_7Series_MIS_v2.4.df//*****************************************************************************`timescale1s/1smoduleexamle_to(//systemsignalsinutsys_rst,inutsys_clk_i,//alicationsignalsinut[15:0]switch_i,outut[15:0]led,outut[7:0]an,outut[7:0]select_seg,//DDR2chisignalsinout[15:0]ddr2_dq,inout[1:0]ddr2_dqs_n,inout[1:0]ddr2_dqs_,outut[12:0]ddr2_addr,outut[2:0]ddr2_ba,oututddr2_ras_n,oututddr2_cas_n,oututddr2_we_n,outut[0:0]ddr2_ck_,outut[0:0]ddr2_ck_n,outut[0:0]ddr2_cke,outut[0:0]ddr2_cs_n,outut[1:0]ddr2_dm,outut[0:0]ddr2_odt);arameterDQ_WIDTH=16;arameterECC_TEST="OFF";arameterADDR_WIDTH=27;arameternCK_PER_CLK=4;localaramDATA_WIDTH=16;localaramPAYLOAD_WIDTH=(ECC_TEST=="OFF")?DATA_WIDTH:DQ_WIDTH;localaramAPP_DATA_WIDTH=2*nCK_PER_CLK*PAYLOAD_WIDTH;localaramAPP_MASK_WIDTH=APP_DATA_WIDTH/8;//Wiredeclarationsrega_en,a_wdf_wren,a_wdf_end;reg[2:0]a_cmd;reg[ADDR_WIDTH-1:0]a_addr;reg[APP_DATA_WIDTH-1:0]a_wdf_data;wire[APP_DATA_WIDTH-1:0]a_rd_data;wire[APP_MASK_WIDTH-1:0]a_wdf_mask;wirea_rdy,a_rd_data_end,a_rd_data_valid,a_wdf_rdy;//***************************************************************************wire[7:0]an;wire[7:0]select_seg;reg[31:0]digit_data;always@(osedgesys_clk_i)beginif(switch_i[3])digit_data<=a_addr;elsecase(switch_i[1:0])2'b00:digit_data<=read_data[31:0];2'b01:digit_data<=read_data[63:32];2'b10:digit_data<=read_data[95:64];2'b11:digit_data<=read_data[127:96];endcaseenddigitU2(.wb_clk_i(sys_clk_i),.wb_rst_i(~sys_rst),.wb_dat_i(digit_data),.an(an),.select_seg(select_seg));reg[1:0]read_valid=2'b0;reg[127:0]read_data=128'h0;always@(osedgea_rd_data_valid)beginread_data=a_rd_data;read_valid[0]=(a_rd_data==data0);read_valid[1]=(a_rd_data==data1);endassignled[15]=a_en;assignled[14]=init_calib_comlete;assignled[13]=a_rdy;assignled[12]=a_wdf_rdy;assignled[4]=sys_rst?read_valid[1]:1'b0;assignled[3]=sys_rst?read_valid[0]:1'b0;assignled[2]=sto_w[1];assignled[1]=sto_w[0];assignled[0]=a_cmd[0];reg[15:0]counter=16'h0;arametercnt_init=16'h1;//minimum:1reg[26:0]addr0=27'h000_0008;reg[26:0]addr1=27'h003_0100;reg[127:0]data0=128'h1111_2222_3333_4444_5555_6666_7777_8888;reg[127:0]data1=128'h9999_0000_aaaa_bbbb_cccc_dddd_eeee_ffff;reg[1:0]sto_w=2'b00;always@(osedgesys_clk_iornegedgesys_rst)beginif(sys_rst==1'b0)begincounter=12'b0;sto_w=2'b0;a_en=1'b0;a_addr=27'h0;a_cmd=3'b1;a_wdf_data=128'h0;a_wdf_end=1'b0;a_wdf_wren=1'b0;endelsebeginif(counter==cnt_init&am;&am;~sto_w[0])if(a_rdy&am;a_wdf_rdy)begina_wdf_data=data0;a_addr=addr0;a_cmd=3'b0;a_wdf_wren=1'b1;a_wdf_end=1'b1;a_en=1'b1;endelse//Holdsecificsignalsuntila_wdf_rdyisasserted.counter=counter-16'h1;elseif(counter==cnt_init+1&am;&am;~sto_w[0])if(a_rdy&am;a_wdf_rdy)begina_wdf_end=1'b0;a_wdf_wren=1'b0;a_en=1'b0;a_cmd=3'b1;sto_w[0]=1'b1;endelse//Holdsecificsignalsuntila_wdf_rdyisasserted.counter=counter-16'h1;elseif(counter==cnt_init+8&am;&am;~sto_w[1])if(a_rdy&am;a_wdf_rdy)begina_wdf_data=data1;a_addr=addr1;a_cmd=3'b0;a_wdf_wren=1'b1;a_wdf_end=1'b1;a_en=1'b1;endelse//Holdsecificsignalsuntila_wdf_rdyisasserted.counter=counter-16'h1;elseif(counter==cnt_init+9&am;&am;~sto_w[1])if(a_rdy&am;a_wdf_rdy)begina_wdf_end=1'b0;a_wdf_wren=1'b0;a_en=1'b0;a_cmd=3'b1;sto_w[1]=1'b1;endelse//Holdsecificsignalsuntila_wdf_rdyisasserted.counter=counter-16'h1;elseif(counter==cnt_init+88)begina_addr=switch_i[2]?addr1:addr0;a_en=1'b1;if(~a_rdy)counter=counter-16'h1;endelseif(counter==cnt_init+89)a_en=1'b0;counter=counter+16'h1;endend//StartofUserDesigntoinstance//***************************************************************************//TheUserdesignisinstantiatedbelow.Thememoryinterfaceortsare//connectedtotheto-levelandthealicationinterfaceortsare//connectedtothetrafficgeneratormodule.Thisrovidesareference//forconnectingthememorycontrollertosystem.//***************************************************************************my_ddru_my_ddr(//Memoryinterfaceorts.ddr2_cs_n(ddr2_cs_n),.ddr2_addr(ddr2_addr),.ddr2_ba(ddr2_ba),.ddr2_we_n(ddr2_we_n),.ddr2_ras_n(ddr2_ras_n),.ddr2_cas_n(ddr2_cas_n),.ddr2_ck_n(ddr2_ck_n),.ddr2_ck_(ddr2_ck_),.ddr2_cke(ddr2_cke),.ddr2_dq(ddr2_dq),.ddr2_dqs_n(ddr2_dqs_n),.ddr2_dqs_(ddr2_dqs_),.ddr2_dm(ddr2_dm),.ddr2_odt(ddr2_odt),//Alicationinterfaceorts.a_addr(a_addr),.a_cmd(a_cmd),.a_en(a_en),.a_wdf_rdy(a_wdf_rdy),.a_wdf_data(a_wdf_data),.a_wdf_end(a_wdf_end),.a_wdf_wren(a_wdf_wren),.a_rd_data(a_rd_data),.a_rd_data_end(a_rd_data_end),.a_rd_data_valid(a_rd_data_valid),.a_rdy(a_rdy),.a_sr_req(1'b0),.a_ref_req(1'b0),.a_zq_req(1'b0),.a_wdf_mask(16'h0000),.init_calib_comlete(init_calib_comlete),//SystemClockPorts.sys_clk_i(sys_clk_i),//ReferenceClockPorts.clk_ref_i(sys_clk_i),.sys_rst(sys_rst));endmodule保存后直接生成比特流就可以下板验证了。在摸索过程中笔者发现,写入了数据之后最快要到发出写命令的第8个系统时钟才能读出所写入的数据,且读操作必须在写操作后经过8的整数倍个时钟后进行。有时将比特流下载到N4DDR上面之后读写的数据有误,但是重启开发板再重新下载即可解决问题,知道个中缘由的朋友欢迎在评论中告知笔者,笔者在此先行谢过。需要说明的是,此处突发长度(BL)为8,因此a_addr必须是8对齐的地址。同时,由于前面选择的DataWidth为16,因此每次读写数据的长度为8*16bit==128bit。·参考文档:Nexys4-DDR_rm.dfug586_7Series_MIS_v2.4.df·模板工程下载链接:htt://download.csdn.net/detail/qq_20091945/9728980·测试代码下载链接:htt://download.csdn.net/detail/qq_20091945/9725407【注意】由于工程大小超出上限,此处仅提供工程的源码文件和比特流文件。·DDR2IP核引脚约束文件下载链接:n4ddr_ddr2_io_assign.ucf转自:blog.csdn.net/qq_20091945/article/details/53940712作者:SEU_MJ
    亮了(0) 21 0 12-13
  • Vivado仿真
    今天说的vivado的仿真是指用vivado自带的仿真工具进行仿真,主要内容集中在如何运用脚本对代码进行仿真。1.Vivado自带工具的图形界面仿真很简单,这里不做过多介绍,但是在图形界面仿真的时候有一点值得注意,就是如何产生设计中所有信号的波形,因为一般Vivado是默认产生顶层模块的IO波形,而如果想产生其他信号的波形,还要在仿真之前添加进去,而如果仿真期间还要加信号的话,就只能重新添加信号,然后重新仿真。所以这里我们利用verilog中的dumvars系统调用来dum出所有的波形。做法就是在仿真设置下面加一条命令-testlusargdum_all。这个命令会被代码中的if($test$lusargs("dum_all"))begin捕捉到,从而会执行$dumfile("board.vcd");$dumvars(0,board);系统调用函数来dum出所有的波形。2.下面主要说一下怎么在命令行界面进行仿真:在命令行界面进行仿真就必须了解vivado的仿真机理,例如,----源代码是如何被编译,然后执行的;----如果设计中包含i核,仿真的过程有事怎样的;----有些i核对应的有源码,而有些i核实没有源码的,这个时候该利用什么队i核进行仿真;首先,Vivado的命令行仿真是可以脱离vivado环境来实现的,就想第三方仿真工具仿真一样。在vivado中,用于仿真的工具有三个:xvlog,xelab,xsim。分别对应comile,elaboration和simulation。下面我们就从这三个方面对应vivado的命令行仿真就行介绍。xvlog:在仿真之前,我们要对源代码进行analyze,关于xvlog这一段究竟做了什么,我现在还不是很清楚。因为从vivado的userguide和实际的命令行仿真来看,编译是在xelab下完成的,所以xvlog具体做了什么,我也很模糊。xvlog有几个重要的命令参数,-i:只include文件,用于代码中的·include语句的文件查找;-f:是对应源码文件的集合,即可以看代码的路径卸载一个文件里,然后用-f进行连接。xvlog最后会输出一个work文件夹,作为后面xelab编译时的模块的查找,work文件夹其实就是用户代码转换成的一个lib库。这里就要说明一下,如果设计中包含没有源码的i核,该怎么办,其实i核本身没有源码,不代表仿真的时候没有源码可以参考,在生成i的过程中,一般也会生成的用于仿真的verilog模型文件,我们仿真的时候只需把这个文件加到我们的源代码中即可,即把这个verilog模型文件就看做是我们的源码文件。xelab:这是对代码进行编译和解析,最后生成可执行文件。xelab也有很多地方需要说,首先就是xelab是怎么利用xvlog产生的work库的,这就涉及到xelab时怎么进行模块的查找的,xelab会默认查找work文件夹,这个不要我们指定,但是如果代码中用到了vivado软件中自带的其他的库,那么我们就要指定了,指定的方式就是利用-L参数,可以利用多个-L参数来指定多个lib;然后,在xelab中,我们必须指定顶层的模块,如果顶层模块指定错误,我们的仿真就会出现很难察觉的错误,我就是经历过这样的教训,还有如果设计中包含i核,我们就要同时指定glbl为顶层模块,关于glbl的作用,这里暂且不说,以后会有总结;最后,我们需要为利用-s参数生成一个snashot文件,即仿真阶段的可执行文件。xsim:这就是真正进行仿真的工具了,在这里我们利用利用-testlusargdum_all来dum所有的波形,同时也可以利用-t参数指定某个tcl脚本来运行,tcl脚本可以指定仿真运行的时间等。其实命令行的仿真和图形界面的过程是一样的,但是从命令行仿真我们更可以看出vivado仿真的具体流程,而不是只停留在鼠标点击某个botton的层面上,这就是命令行最大的好处吧,下面给出我的命令行的脚本作为参考:#simulationscrit#rm-rfxsim.*rm-fxsim_1*rm-fxvhdl.*rm-fxvlog.*rm-felaborate.*rm-f*.log##comilesourceandsimulationfile#echo"comilesourceandsimulationfile"xvlog-m64-itests/-idsort/-ifunctional/-fxilinx_lib.f-fsource-design-list.f-fsource-i-list.f-fsource-simulation-list.f;##elaboratethedesign-list#echo"elaboratethedesign"xelabwork.boardwork.glbl-m64--debugtyical--mt8-Lxil_defaultLib-Lxm-Lblk_mem_gen_v8_3_2-Lunisims_ver-Lunimacro_ver-Lsecurei--snashotboard_behave-logelaborate.log;#-Lxil_defaultLib-Lxm-Lblk_mem_gen_v8_3_2-Lunisims_ver-Lunimacro_ver-Lsecurei#startsimulationthedesign#-Lxil_defaultLib-Lxm-Lblk_mem_gen_v8_3_2-Lunisims_ver-Lunimacro_ver-Lsecurei#echo"startsimulation"xsimboard_behave-testlusargdum_all-testlusargsamle_smoke_test0-tsimulation_control.tcl-logsimulation.log
    亮了(0) 23 0 12-13
解决问题:57
干货热帖:147
会员总数:7107
总帖数:561
我要发帖

贡献榜

  • hahavchen

    创新创业教育知名圈内人

    常隐匿于江湖的资深攻城狮,拥有超过10年的半导体与测控行业产品研发、技术支持、市场拓展及区域销售经验。目前同时担任上海交通大学本科生企业导师。

    • 王斌Jr

      工程师

      Andorid工程师,书呆子

    • mysunday2

      本科生

      武汉大学在读研究生,懂一点Java,懂一点LabVIEW

    • 风雨兼程

      本科生

      热爱科研,忠于技术,渴望在LabVIEW的世界里遨游。

    • 地板

      媒体人

      资深媒体人,现任职于国内某知名电子行业媒体

  • EltonLiang

    工程师

    汽车电子方向系统集成工程师,坐标北京。精通LabVIEW与测控技术,乐于分享总结。

    • Superlava

      工程师

      国家电网工程师,对于创新创造,我是真爱粉!

    • chnwjian

      研究生

      擅长物理实时测量和ardunio

    • linon

      教师

      东南大学电子科学与工程学院

    • suo ivy

      创业者

      乐忠于机器人的创业少年

  • CC

    研究生

    擅长FPGA以及LabVIEW程序设计,拥有多年项目开发经验,曾开发过高速误码仪、自动泊车系统,研发并将PM2.5检测仪推入市场,目前致力于FPGA的图像处理研究。

    • 冰淇淋

      研究生

      略懂c语言,爱玩爱交流

    • Veritas

      电子技术爱好者

      非电类专业的在校纯技术爱好者

    • 竹杖芒鞋轻胜马

      研究生

      擅长电子电力,电源,逆变器,Matlab的同济骚年

    • 熊猫家的猫

      研究生

      热爱电子设计,熟悉LabVIEW编程,希望和大家一起学习进步。

    • 李比希

      电子技术爱好者

      喜欢LabVIEW,会点c语言,痴迷玩创,让激情碰出创意的火花!

    • 糊涂宝宝

      研究生

      精通C语言与电路设计。善于软硬件结合开发实际工程项目。

    • LabVIEWers

      工程师

      汽车电子电控领域工程师。个人信条:追求卓越。

    • 南瓜粥

      本科生

      致力于精密测量@天津大学

  • philo

    工程师

    刚毕业的新晋TI验证工程师一枚。内心埋有一个小小的希望靠技术改变世界的种子。CLD(认证LabVIEW开发工程师)持有者,并熟悉C语言与MATLAB。

    • 阳光的新手125

      研究生

      Strict coding is the boddy, smart thoughts are the soul.

    • AoduLabVer

      工程师

      华为数字视频领域工程师,技术宅,CLD,热衷LabVIEW

    • 西兰花教负责人

      创业者

      俗称“福建三本“的某985高校毕业,正不务正业地创业中

    • berwin

      创业者

      好奇主义 & 观察者 & 行动派

  • RockMOOC

    教师

    博士,现于哈尔滨工业大学任教。拥有超过8年基于FPGA的数字系统硬件设计经验,精通FPGA开发。

    • wonderm

      本科生

      熟悉LabVIEW/Matlab/Verilog,擅长STM32/K60硬件开发

    • diguaguowang

      研究生

      一直羡慕会各种编程的人,也在向着这个方向努力

    • 阿Q

      工程师

      精通FPGA的酷创达人

    • wigger

      工程师

      Digilent元老级大牛

  • Mr. D

    工程师

    部落的发起者与第一位"Digger",非典型张江男一枚。致力于为有执着有梦想的志同道合者缔造一个可以互相勾搭的中文开源技术社区。