<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/xsl/rss.xsl" type="text/xsl" media="screen"?>
<!--åå®¢åå«æ¥å¿ï¼æ¯äºèç½ä¸ä¸ç§ä¸ªäººä¹¦ååäººéäº¤æµçå·¥å·ãéè¿åå®¢è®°å½ä¸å·¥ä½ãå­¦ä¹ ãçæ´»åå¨±ä¹çç¹æ»´ï¼çè³è§ç¹åè¯è®ºï¼ä»èå¨ç½ä¸å»ºç«ä¸ä¸ªå®å¨å±äºèªå·±çä¸ªäººå¤©å°ãå»ºç«åå®¢ï¼æå©äºä»äººå¨äºèç½ä¸æ´å¥½å°è®¤è¯æ¨ï¼ä¹æå©äºæ¨æ´å¥½çåå«äººäº¤æµãåå®¢ä¸çæ¯ä¸ä¸ªå¼æ¾åå±äº«çä¸çãæçåå®¢ç±æçå¬å¸å¼åï¼ç®åæ¯åè´¹æå¡ã--> 
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:ppp="http://blog.sohu.com/ppp/"
	>

	<channel>
		<title>地狱男孩</title>
		<link>http://hellboy158.blog.sohu.com/</link>
		<description><![CDATA[地狱男孩]]></description>
		<pubDate>Tue, 8 Apr 2008 11:00:37 +0800</pubDate>
		<ppp:ebi>28ecc09792</ppp:ebi>
		<generator>搜狐博客</generator>
		<image>
			<title>http://blog.sohu.com</title>
			<url>http://js.pp.sohu.com/ppp/blog/images/common/logo_150_60.gif</url>
			<link>http://blog.sohu.com/</link>
			<width>100</width>
			<height>43</height>
			<description>搜狐博客</description>
		</image>
		<item>
			<title>Verilog inout 双向口使用和仿真</title>
			<link>http://hellboy158.blog.sohu.com/84072483.html</link>
			<comments>http://hellboy158.blog.sohu.com/84072483.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 8 Apr 2008 11:00:37 +0800</pubDate>
			<category>学习_FPGA</category>
			<guid>http://hellboy158.blog.sohu.com/84072483.html</guid>
			<description><![CDATA[<p><br />芯片外部引脚很多都使用inout类型的，为的是节省管腿。一般信号线用做总线等双向数据传输的时候就要用到INOUT类型了。就是一个端口同时做输入和输出。 inout在具体实现上一般用三态门来实现。三态门的第三个状态就是高阻'Z'。 当inout端口不输出时，将三态门置高阻。这样信号就不会因为两端同时输出而出错了。</p>
<p><br />对双向口，我们可以将其理解为2个分量：一个输入分量，一个输出分量。另外还需要一个控制信号控制输出分量何时输出。此时，我们就可以很容易地对双向端口建模。</p>
<p>例子：<br />CODE:<br />module dual_port (<br />....<br />inout_pin,<br />....<br />);</p>
<p>inout inout_pin;</p>
<p>wire inout_pin;</p>
<p>wire input_of_inout;<br />wire output_of_inout;<br />wire out_en;</p>
<p>assign input_of_inout = inout_pin;</p>
<p>assign inout_pin = out_en ? output_of_inout : 高阻;</p>
<p>endmodule</p>
<p>可见，此时input_of_inout和output_of_inout就可以当作普通信号使用了。</p>
<p>在仿真的时候，需要注意双向口的处理。如果是直接与另外一个模块的双向口连接，那么只要保证一个模块在输出的时候，另外一个模块没有输出（处于高阻态）就可以了。<br />如果是在ModelSim中作为单独的模块仿真，那么在模块输出的时候，不能使用force命令将其设为高阻态，而是使用release命令将总线释放掉</p>
<p>很多初学者在写testbench进行仿真和验证的时候，被inout双向口难住了。仿真器老是提示错误不能进行。下面是我个人对inout端口写testbench仿真的一些总结，并举例进行说明。在这里先要说明一下inout口在testbench中要定义为wire型变量。</p>
<p>先假设有一源代码为：</p>
<p>module xx(data_inout , ........);</p>
<p>inout data_inout;</p>
<p>........................</p>
<p>assign data_inout=(! link)?datareg:1'bz;</p>
<p>endmodule</p>
<p>方法一：使用相反控制信号inout口，等于两个模块之间用inout双向口互连。这种方法要注意assign 语句只能放在initial和always块内。</p>
<p>module test();</p>
<p>wire data_inout;</p>
<p>reg data_reg;</p>
<p>reg link;</p>
<p>initial begin</p>
<p>..........</p>
<p>end</p>
<p>assign data_inout=link?data_reg:1'bz;</p>
<p>endmodule</p>
<p>方法二：使用force和release语句，但这种方法不能准确反映双向端口的信号变化，但这种方法可以反在块内。</p>
<p>module test();</p>
<p>wire data_inout;</p>
<p>reg data_reg;</p>
<p>reg link;</p>
<p>#xx;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //延时</p>
<p>force data_inout=1'bx;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //强制作为输入端口</p>
<p>...............</p>
<p>#xx;</p>
<p>release data_inout;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //释放输入端口</p>
<p>endmodule<br /></p>]]></description>
		</item>
		    
		
		<item>
			<title>构造一个51单片机的实时操作系统</title>
			<link>http://hellboy158.blog.sohu.com/63282695.html</link>
			<comments>http://hellboy158.blog.sohu.com/63282695.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Sun, 9 Sep 2007 08:44:53 +0800</pubDate>
			<category>学习_单片机及电路设计</category>
			<guid>http://hellboy158.blog.sohu.com/63282695.html</guid>
			<description><![CDATA[<h4>&nbsp;</h4>
<div></div>
<div>摘 要：从Keil C51的内存空间管理方式入手,着重讨论实时操作系统在任务调度时的重入问题,分析一些解决重入的基本方式与方法：分析实时操作系统任务调度的占先性,提出非占先的任务调度是能更适合于Keil C51的一种调度方式。为此,构造这一实时操作系统,并有针对性地介绍此系统的堆管理方法、任务的建立以厦任务的切换等。 <br />关键词：51单片机 实时操作系统 任务重八调度 <br /><br />目前,大多数的产品开发是在基于一些小容量的单片机上进行的。51系列单片机,是我国目前使用最多的单片机系列之一,有非常广大的应用环境与前景,多年来的资源积累,使51系列单片机仍是许多开发者的首选。针对这种情况,近几年涌现出许多基于51内核的扩展芯片,功能越来越齐全,速度越来越快,也从一个侧面说明了51系列单片机在国内的生命力。 <br /><br />多年来我们一直想找一个合适的实时操作系统,作为自己的开发基础。根据开发需求,整合一些常用的嵌入式构件,以节约开发时间,尽最大可能地减少开发工作量;另外,要求这个实时操作系统能非常容易地嵌入到小容量的芯片中。毕竟,大系统是少数的,而小应用是多数而广泛的。显而易见,&mu;C／OS&mdash;II是不太适合于以上要求的,而Keil C所带的RTX Tiny不带源代码,不具透明性,至于其FULL版本就更不用说了。<br /><br /><br />1 KeiI C51与重入问题 <br />说到实时操作系统,就不能不考虑重入问题。对于PC机这样的大内存处理器而言,这似乎并不是一个很麻烦的问题,借用&mu;C／OS&mdash;II RTOS的说法,即要求在重入的函数内,使用局部变量。但5l系列单片机堆栈空间很小,仅局限在256字节之内,无法为每个函数都分配一个局部堆空间。正是由于这个原因,Keil C51使用了所谓的可覆盖技术： <br />①局部变量存储在全局RAM空间(不考虑扩展外部存储器的情况); <br />②在编译链接时,即已经完成局部变量的定位; <br />③如果各函数之间没有直接或间接的调用关系,则其局部变量空间便可覆盖。 <br /><br />正是由于以上的原因,在Keil C51环境下,纯粹的函数如果不加处理(如增加一个模拟栈),是无法重人的。那么在Keil C5l环境下,如何使其函数具有可重人性呢?下面分析在实时操作系统下面,任务的基本结构与模式： <br />vold TaskA(void*ptr){ <br />UINT8 vaL_a; <br />／／其他一些变量定义 <br />do{ <br />／／实际的用户任务处理代码 <br />}while(1); <br />} <br />void TaskB(void*ptr){ <br />UINT8 vaLb; <br />／／其他一些变量定义 <br />do{ <br />Funcl(); <br />／／其他实际的用户任务处理代码 <br />)while(1); <br />void Funcl(){ <br />UlNT8 v al_fa; <br />／／其他变量的定义 <br />／／函数的处理代码 <br />} <br /><br />在上面的代码中,TaskA与TaskB并不存在直接或间接的调用关系,因而其局部变量val_a与val_b便是可以被互相覆盖的,即其可能都被定位于某一个相同的RAM空间。这样,当TaskA运行一段时间,改变了val_a后,TaskB取得CPU控制权并运行时,便可能会改变val_b。由于其指向相同的RAM空间,导致TaskA重新取得CPU控制权时,val&mdash;a的值已经改变,从而导致程序运行不正确,反过来亦然。另一方面,Funcl()与TaskB有直接的调用关系,因而其局部变量val_fa与val_b不会被互相覆盖,但也不能保证其局部变量val_fa不会与TaskA或其他任务的局部变量形成可覆盖关系。 <br /><br />将val_a、val_b以及val_fa等局部变量定义为静态变量(加上static指示符)可以解决这一问题。但问题是,定义大量的static类型变量,将导致RAM空间的大量占用,有可能直接导致RAM空间不够用。尤其是在一些小容量的单片机内,一般只有128或256字节,大量的静态变量定义,在如此小的RAM资源状况下显然就不太合适了。由此而有了另一种的解决方法,如下代码所示： <br />void TaskC(void){ <br />UINT8 x,v; <br />whlk(1){ <br />OS_ENTER_CRITICAL(); <br />x=GetX(); (1) <br />y=GetY(); (2) <br />／／任务的其他代码 <br />OS_EXIT_CRITICAL(); (3) <br />0SSleep(100); (4) <br />} <br />} <br /><br />以上代码TaskC中使用了临界保护的方法来保护代码不被中断占先,确实有效地解决了RAM空间太小,不宜大量定义静态变量的问题。然而如果每个任务都采用此种结构,任务一开始,就关闭中断,将使实时性得不到保证。事实证明,这种延时是相当可观的。用一个实例来说明,如果想在系统中使用一个动态刷新的LED显示器,就难以保证显示的稳定与连续,哪怕在系统中是使用一个单独的定时器来做这一工作(进入临界区后,EA=0)。其次,这种结构事实上将占先的任务调度转化为非占先的任务调度。实际上如果在(3)与(4)之间没有碰巧发生中断并导致一个任务调度,那就可以理解为是任务主动放弃CPU的控制。如果在(3)和(4)之间碰巧产生了一个中断并导致了一个任务调度,只是执行了一次多余的任务调度而已,而且并不希望在(3)之后发生2次甚至多次的任务调度,相信读者也有这一愿望。 <br /><br />除此之外,还可以发现任务的一个特点：当任务从(1)重新开始时,局部变量x和y是一个什么值并不在乎,即x和y即使在(3)之后改变了,也已经不再重要,不会影响程序的正确性。其实这一特点也是大部分任务,至少是太部分任务的大部分局部变量的一个共性&mdash;&mdash;如果任务在整个执行过程中,不会(被占先)放弃CPU控制权,则其局部变量大多数并不需要进行特别的保护,即其作用域只是任务的当次执行,针对上面的代码,就是临界保护区内的代码区域。 <br /><br />2 实时操作系统要不要占先 <br />由上面的分析,如果要保持一个函数可重人,就得使用静态变量,系统的RAM资源将是一个严峻的考验;如果使用临界区来保护运行环境,系统的实时性又得不到保证,而且有将占先式任务调度转为非占先任务调度之虞。显然,使用静态变量简单,但有更多的不适用性,对将来功能的调整也是一个阻碍,一般不被采用。那么,就只能从环境保护上来下功夫了,但是果真只能以进入临界区牺牲系统的实时性来保证任务不被占先?下面看看临界保护这一方法的基本思路： <br />①在一个任务中,如果局部变量在其作用域内不被占先切换,则这些变量在任务被剥夺了CPU控制权后,不关心其值也不会影响任务的正确执行; <br />②使用临界区保护,可以达到上面所提到的要求; <br />③由此导致的实时性能与占先切换的减弱可以接受。由此可知,不被占先是任务保护局部变量的关键。既然如此,何不舍弃占先式的任务调度?这不失为一个好的出发点。针对Keil C51,非占先式任务调度,可能是一种更好的方法,更能协调51系列单片机的既定资源。下面编写这样一个系统： <br />①使用非占先式任务调度; <br />②可以在小容量的芯片中使用,开发目标是,即使是8051这样小的芯片,也可使用这个实时操作系统; <br />③支持优先级调度,尽可能保证其实时性。 <br /><br />3 实时操作系统的实现 <br />基于以上的分析与目的,近日完成了这个操作系统。在堆栈上借用RTx的管理方法,即当前任务使用全部的堆空间 <br /><br />3.1 堆栈的初始化与任务的创建 <br />堆栈的初始化实际是初始化0STaskStackBotton数组,并将当前任务指定为空闲任务,下一个运行任务指定为最高优先级任务,即优先级为零的任务。初始化时,将SP的值存人OSTaslkStackBotton[O],SP+2的值存入OSTaskStacKBotton[1],依此类推。而任务是调用0STa-skCreate函数建立的。实际上只是将任务(假设为n号任务)的地址填人到对应OSTaskStackBotton[n]所指向的位置,并将SP向后移动2个字节, <br /><br />为什么要以这样一种规律而不是其他的方式呢?这是由于在任务建立后,还未进行任务调度之前,各任务的堆栈实际上是它们自身的地址,因而其堆栈深度为2,为了程序的简便而直接填入。 <br />void main(void){ <br />OSInit(); ／*初始化OSTaskStackBcBotton队列*／ <br />TMOD=(TMOD&amp;0XFO)│ 0XOl; <br />TL0=0xBF; <br />TH0=0xFC; <br />TRO=1; <br />ETO=1; <br />TFO=O： <br />OSTaskCreate(TaskA,NULL,0); <br />OSTaskCreate(TaskB．NULL,1); <br />OSTaskCreate(TaskC,NULL,2); <br />OSStart(); <br /><br />上面这段代码中,所有任务建立后,便调用OSStart()开始任务调度。OSStart()是一个宏定义,如下所示： <br />#deflne OSStart() d0{＼ <br />OSTaskCreate(TaskIdle,NULL,OS_MAX_TASKS);＼ <br />EA=l：＼ <br />return;＼ <br />}while(O) <br /><br />首先,它创建了一个空闲任务并打开中断,然后便返回。返回到哪里了呢?我们知道,空闲任务是优先级最低的任务,当调OSTaskCreate建立时,会将其地址填人到SP的位置,并把SP向后移动2个字节(见图2及说明),因而此时处在堆栈顶端的,一定是空闲任务Taslddle。这就使得这里的return一定会返回到空闲任务。至此,系统进入正常运行状态。 <br /><br />3．2 任务的切换 <br />任务的切换分两种情况,在当前任务优先级低于下一个取得CPU控制权的任务时,将下一个取得CPU控制权的任务的栈顶到当前任务的栈顶之间的内容向RAM空间的高端搬移,以空出全部的RAM空间作下一个任务的堆空间,同时更新对应的OSTaskStackBotton,使其指向新的正确任务的堆栈栈底。如果当前任务的优先级高于下一个任务的优先级,则作相反的搬移, <br /><br />所有任务必须主动调用OSSleep,放弃CPU的控制权。任务调用OSSleep后,将选择优先级最高的就绪任务运行。 <br /><br />结 语 <br />系统完成后,内核的代码量在400多个字节左右,占用1个定时器中断及小量的内存空间。系统设置容量为8个任务,用户实际可用任务为7个,能够满足一般需求,也达到了在小容量芯片中应用的开发要求。由于没有采用占先式的任务调度,除开全程相关的个别任务的一些局部变量外,其他局部变量已经不存在覆盖关系,由于是任务主动放弃CPU控制权,对于个别需要保护的变量单独进行处理也变得容易。在系统中,全程不需要反复地开关中断,实时性能也很好。对个别时序要求严格的外设(如DSl8820)除外。 <br /></div>]]></description>
		</item>
		    
		
		<item>
			<title>对开学第一周进行一下总结</title>
			<link>http://hellboy158.blog.sohu.com/63129877.html</link>
			<comments>http://hellboy158.blog.sohu.com/63129877.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Fri, 7 Sep 2007 21:34:58 +0800</pubDate>
			<category>心情</category>
			<guid>http://hellboy158.blog.sohu.com/63129877.html</guid>
			<description><![CDATA[<p>&nbsp; 不知不觉已经开学一周了，总体总觉这周过的很充实，但是也很累！</p>
<p>&nbsp;&nbsp;这周完成的主要工作就是完成了开题报告和演讲稿的撰写，使系统中的问题更加清晰了；再者整理了一篇论文，并且投了出去。</p>
<p>&nbsp;&nbsp; 通过这一周的学习和认识，这学期的任务十分艰巨。一要完成毕业设计的大部分工作（算法确定；构建硬件系统；调试软件；完成样机的调试）二就是找工作。这两项任务可都是很艰巨的，而且需要大量的精力。只恨时间飞逝阿！</p>
<p>&nbsp;&nbsp; 这毕设和找工作两者间，我选择先把精力放于毕业设计。确定研究方案，明确系统的研究重点和难点。下面就是一个一个解决这些问题。可惜身边没有人可以指导啊！有些问题可能解决起来比较困难，但是肯定是可以解决的。现在自己摸索吧。把最近要攻克的难点列出来，希望能够督促自己尽快解决，不要偷懒！</p>
<p>&nbsp; （1）确定图像处理算法（下周）</p>
<p>&nbsp; （2）验证基本的SOPC系统的构建；调试CameraLink模块，主要观察相机的信号是否能够进入FPGA中。（一周或两周）</p>
<p>&nbsp; （3）深入学习SOPC中外围器件的使用，能够将相机的数据存进来（两周）。</p>
<p>&nbsp; （4）完全定制SOPC硬件系统，移植操作系统，开发以太网。（一个月）</p>
<p>&nbsp; （5）硬件实现图像处理算法,移植到SOPC系统中（一个月）。</p>
<p>&nbsp;&nbsp; 下周努力啊！</p>]]></description>
		</item>
		    
		
		<item>
			<title>人生哲理</title>
			<link>http://hellboy158.blog.sohu.com/58783826.html</link>
			<comments>http://hellboy158.blog.sohu.com/58783826.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 7 Aug 2007 14:12:56 +0800</pubDate>
			<category>心情</category>
			<guid>http://hellboy158.blog.sohu.com/58783826.html</guid>
			<description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 人生犹如长途旅行，不断有过客，人生有太多的变数，又有几个人，可以真心不变呢？人唯一可以依靠的，只有自己，自己才是命运的主宰&hellip;&hellip;以下几句人生哲理我非常喜欢，细细品味，别有一番滋味哦！或许也会带给你有意外的收获和感悟。</p>
<p>&nbsp;&nbsp;&nbsp; 1、能冲刷一切的除了眼泪，就是时间，以时间来推移感情，时间越长，冲突越淡，仿佛不断稀释的茶。</p>
<p>&nbsp;&nbsp;&nbsp; 2、如果朋友让你生气，那说明你仍然在意他的友情。</p>
<p>&nbsp;&nbsp;&nbsp; 3、快乐要有悲伤作陪，雨过应该就有天晴。如果雨后还是雨，如果忧伤之后还是忧伤．请让我们从容面对这离别之后的离别。微笑地去寻找一个不可能出现的你！</p>
<p>&nbsp;&nbsp;&nbsp; 4、你出生的时候，你哭着，周围的人笑着；你逝去的时候，你笑着，而周围的人在哭！一切都是轮回!我们都在轮回中!</p>
<p>&nbsp;&nbsp;&nbsp; 5、人生短短几十年，不要给自己留下了什么遗憾，想笑就笑，想哭就哭，该爱的时候就去爱，无谓压抑自己。</p>
<p>&nbsp;&nbsp;&nbsp; 6、我不去想是否能够成功,既然选择了远方,便只顾风雨兼程；我不去想,身后会不会袭来寒风冷雨,既然目标是地平线,留给世界的只能是背影。</p>
<p>&nbsp;&nbsp;&nbsp; 7、有人说&ldquo;有些事情本身我们无法控制，只好控制自己。&rdquo;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 8、每个人都有潜在的能量，只是很容易:被习惯所掩盖，被时间所迷离,被惰性所消磨。</p>
<p>&nbsp;&nbsp;&nbsp; 9、后悔是一种耗费精神的情绪。后悔是比损失更大的损失,比错误更大的错误。所以不要后悔。 </p>
<p>&nbsp;&nbsp;&nbsp; 10、我不知道我现在做的哪些是对的，那些是错的，而当我终于老死的时候我才知道这些。所以我现在所能做的就是尽力做好每一件事，然后等待着老死。&nbsp;&nbsp;</p>]]></description>
		</item>
		    
		
		<item>
			<title>图像处理算法综述</title>
			<link>http://hellboy158.blog.sohu.com/58356573.html</link>
			<comments>http://hellboy158.blog.sohu.com/58356573.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Sat, 4 Aug 2007 15:26:35 +0800</pubDate>
			<category>学习_图像处理</category>
			<guid>http://hellboy158.blog.sohu.com/58356573.html</guid>
			<description><![CDATA[<p><font size="3">&nbsp;&nbsp;&nbsp; 图像测量系统的测量原理是通过处理被测物体图像的边缘而获得物体的几何参数。在图像测量系统中，图像边缘提取是测量的基础和关键。早期常用像素级边缘提取方法，主要是一些经典的边缘提取算子算法，如常用的梯度算子、Lapacian算子、<br />Kirsch算子和门式算子等。这些算法的精确度为像素级。随着对测量精确度要求的提高，像素级精确度已经不能满足实际测量的要求，需要更高精确度的边缘提取算法，即亚像素算法。</font></p>
<p><font size="3">&nbsp;&nbsp;&nbsp; 亚像素级精确度的算法是在经典算法的基础上发展起来的，这些算法需先用经典算法找出边缘像素的位置，然后使用周围像素的灰度值作为判断的补充信息，使边缘定位于更加精确的位置。最早应用的亚像素算法是重心法，后来又发展了应用不同原理的其他亚像素提取算法，如概率论法、解调测量法、多项式插值法、滤波重建法以及矩法等。这些算法的精确度和抗噪声能力都不相同，其中以重心法的计<br />算最简单，滤波重建法的精确度最高，矩法对输人数据中的加性噪声和乘性噪声不敏感．</font></p>]]></description>
		</item>
		    
		
		<item>
			<title>利用megafunction定制RAM</title>
			<link>http://hellboy158.blog.sohu.com/57765286.html</link>
			<comments>http://hellboy158.blog.sohu.com/57765286.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Wed, 1 Aug 2007 00:00:27 +0800</pubDate>
			<category>学习_FPGA</category>
			<guid>http://hellboy158.blog.sohu.com/57765286.html</guid>
			<description><![CDATA[<p><font size="4">利用megafunction定制RAM</font></p>
<p>1 two_pram<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;two_pram<br />功能：可以定制简单的双端口RAM。一个端口只能写，一个只能读，有独立的读写地址线。<br />特点：可以增加独立的读写时钟或输入输出时钟；可以定制不同的输入输出端口宽度；可以增加读使能信号。 <br />2 altdpram<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;altdpram<br />功能：可以定制简单的双端口RAM。一个端口只能写，一个只能读，有独立的读写地址线。<br />特点：可以增加独立的读写时钟或输入输出时钟；可以定制不同的输入输出端口宽度；可以增加读使能信号。 <br />3 altsyncram<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;altsyncram<br />功能：可以定制简单ROM,单口RAM,简单双口RAM,真正双口RAM。<br />特点：<br />4 dpram<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;dpram<br />功能：可以定制简单双端口RAM,真正双口RAM。<br />特点：<br />5 csdpram<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;csdpram<br />功能：Parameterized Cycle_shared Dual_port RAM。<br />特点：有busy信号<br />6 lpm_ram_dq&nbsp;<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;lpm_ram_dq<br />功能：定制RAM。<br />特点：输入输出共用双向IO口,但地址线是两套独立,即数据输入时使用输入地址线,输出时使用输出地址线.<br />7 lpm_ram_dp<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;lpm_ram_dp<br />功能：定制RAM。<br />特点：可以构建双端口RAM .<br />6 lpm_ram_io<br />位置：Symbol-&gt;megafunctions-&gt;storage-&gt;lpm_ram_io<br />功能：定制RAM。<br />特点：数据输入输出口为单一的IO口，共用一套地址线。与普通的RAM一样。</p>]]></description>
		</item>
		    
		
		<item>
			<title>two_pram学习</title>
			<link>http://hellboy158.blog.sohu.com/57746408.html</link>
			<comments>http://hellboy158.blog.sohu.com/57746408.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 31 Jul 2007 21:53:57 +0800</pubDate>
			<guid>http://hellboy158.blog.sohu.com/57746408.html</guid>
			<description><![CDATA[<h2>功能：</h2>
<h2>可以定制简单的双端口RAM。一个端口只能写，一个只能读，有独立的读写地址线。<br />特点：</h2>
<h2>可以增加独立的读写时钟或输入输出时钟；可以定制不同的输入输出端口宽度；可以增加读使能信号。&nbsp;</h2>
<h2>
<center>The following waveforms show the behavior of altsyncram megafunction for the chosen set of parameters in design two_pram.v. For the purpose of this simulation, the contents of the memory at the start of the sample waveforms is assumed to be ( F0, F1, F2, F3, ...). The design two_pram.v has one read port and one write port. The read port has 1024 words of 8 bits each and the write port has 1024 words of 8 bits each. The output of the read port is registered by clock. <img src="file:///F:/FPGA_learn/fpga_project/ram_ip_learn/two_pram_wave0.jpg" /> </center></h2>
<h2>
<center>&nbsp;</center></h2>
<h2>
<center><font size="2">Fig. 1 : Wave showing read operation. </font></center></h2>
<h2>
<center>&nbsp;</center></h2>
<h2>
<center><font size="3">The above waveform shows the behavior of the design under normal read conditions. The read happens at the rising edge of the enabled clock cycle. The output from the RAM is undefined until after the first rising edge of the read clock. Read enable port should be enabled for read in the simple dual port mode The clock enable on the read side input registers are disabled. The clock enable on the output registers are disabled. </font></center></h2>
<h2>
<center><img src="file:///F:/FPGA_learn/fpga_project/ram_ip_learn/two_pram_wave1.jpg" /> </center></h2>
<h2>
<center>&nbsp;</center></h2>
<h2>
<center><font size="2">Fig. 2 : Waveform showing write operation </font></center></h2>
<h2>
<center>&nbsp;</center></h2>
<h2>
<center><font size="3">The above waveform shows the behavior of the design under normal write conditions. The write cycle is assumed to be from the rising edge of the enabled clock in which wren is high till the rising edge of the next clock cycle. In DUAL_PORT mode, when the write happens at the same address as the one being read in the other port, the read output is the old data at the address. Actual write into the RAM happens at the falling edge of the write clock. Actual write into the RAM happens at the rising edge or falling edge of the write clock, depending on whether the RAM blocks are assigned to M-RAM or not. In the sample waveforms, they are shown to be on the falling edge of the write clock. The clock enable on the write side input registers are disabled. The clock enable on the output registers are disabled. </font></center></h2>
<h2>
<center>&nbsp;</center></h2>
<h2>
<center>.v </center></h2>
<p align="left">The following waveforms show the behavior of altsyncram megafunction for the chosen set of parameters in design two_pram.v. For the purpose of this simulation, the contents of the memory at the start of the sample waveforms is assumed to be ( F0, F1, F2, F3, ...). The design two_pram.v has one read port and one write port. The read port has 512 words of 8 bits each and the write port has 512 words of 8 bits each. The output of the read port is registered by clock. </p>
<div align="left"><img src="file:///F:/FPGA_learn/fpga_project/ram_ip_learn/two_pram_wave0.jpg" /> </div>
<p align="left">
<div align="left"><font size="2">Fig. 1 : Wave showing read operation. </font></div>
</p><p align="left"></p>
<p align="left"><font size="3">The above waveform shows the behavior of the design under normal read conditions. The read happens at the rising edge of the enabled clock cycle. The output from the RAM is undefined until after the first rising edge of the read clock. Read enable port should be enabled for read in the simple dual port mode The clock enable on the read side input registers are disabled. The clock enable on the output registers are disabled. </font></p>
<div align="left"><img src="file:///F:/FPGA_learn/fpga_project/ram_ip_learn/two_pram_wave1.jpg" /> </div>
<p align="left">
<div align="left"><font size="2">Fig. 2 : Waveform showing write operation </font></div>
</p><p align="left"></p>
<p align="left"><font size="3">The above waveform shows the behavior of the design under normal write conditions. The write cycle is assumed to be from the rising edge of the enabled clock in which wren is high till the rising edge of the next clock cycle. In DUAL_PORT mode, when the write happens at the same address as the one being read in the other port, the read output is the old data at the address. Actual write into the RAM happens at the falling edge of the write clock. Actual write into the RAM happens at the rising edge or falling edge of the write clock, depending on whether the RAM blocks are assigned to M-RAM or not. In the sample waveforms, they are shown to be on the falling edge of the write clock. The clock enable on the write side input registers are disabled. The clock enable on the output registers are disabled. </font></p>
<p align="left"></p>]]></description>
		</item>
		    
		
		<item>
			<title>电子科大tony的工作经验(转载)</title>
			<link>http://hellboy158.blog.sohu.com/57658447.html</link>
			<comments>http://hellboy158.blog.sohu.com/57658447.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 31 Jul 2007 13:35:46 +0800</pubDate>
			<category>学习_FPGA</category>
			<guid>http://hellboy158.blog.sohu.com/57658447.html</guid>
			<description><![CDATA[<p>在公司里的几个月，做的项目其实不多，但是收获还是有一些，我觉得收获最大的是<br />设计理念的改变，这也是我这段时间最想总结的，我会在后面逐渐阐述。<br />&nbsp; &nbsp;版权所有，未经作者允许，禁止用于商业性质的<a href="#"><u><strong>转载</strong></u></a>；如对此文有疑问或想给作者提<br />建议请给作者发email：<a href="mailto:wangdian@tom.com">wangdian@tom.com</a>&nbsp;&nbsp;</p>
<p><strong>１ 时序是设计出来的<br /></strong>&nbsp; &nbsp; 我的boss有在华为及峻龙工作的背景，自然就给我们讲了一些华为及altera做逻辑<br />的一些东西，而我们的项目规范，也基本上是按华为的那一套去做。在工作这几个月中<br />，给我感触最深的是华为的那句话：时序是设计出来的，不是仿出来的，更不是湊出来<br />的。<br />&nbsp; &nbsp; 在我们公司，每一个项目都有很严格的评审，只有评审通过了，才能做下一步的工<br />作。以做逻辑为例，并不是一上来就开始写代码，而是要先写总体设计方案和逻辑详细<br />设计方案，要等这些方案评审通过，认为可行了，才能进行编码，一般来说这部分工作<br />所占的时间要远大于编码的时间。<br />&nbsp; &nbsp; 总体方案主要是涉及模块划分，一级模块和二级模块的接口信号和时序（我们要求<br />把接口信号的时序波形描述出来）以及将来如何测试设计。在这一级方案中，要保证在<br />今后的设计中时序要收敛到一级模块（最后是在二级模块中）。什么意思呢？我们在做<br />详细设计的时候，对于一些信号的时序肯定会做一些调整的，但是这种时序的调整最多<br />只能波及到本一级模块，而不能影响到整个设计。记得以前在学校做设计的时候，由于<br />不懂得设计时序，经常因为有一处信号的时序不满足，结果不得不将其它模块信号的时<br />序也改一下，搞得人很郁闷。<br />&nbsp; &nbsp; 在逻辑详细设计方案这一级的时候，我们已经将各级模块的接口时序都设计出来了<br />，各级模块内部是怎么实现的也基本上确定下来了。<br />&nbsp; &nbsp; 由于做到这一点，在编码的时候自然就很快了，最重要的是这样做后可以让设计会<br />一直处于可控的状态，不会因为某一处的错误引起整个设计从头进行。<br /><br /></p>
<p><strong>２规范很重要<br /></strong>&nbsp; &nbsp; 工作过的朋友肯定知道，公司里是很强调规范的，特别是对于大的设计（无论<a href="#"><u><strong>软件</strong></u></a><br />还是硬件），不按照规范走几乎是不可实现的。逻辑设计也是这样：如果不按规范做的<br />话，过一个月后调试时发现有错，回头再看自己写的代码，估计很多信号功能都忘了，<br />更不要说检错了；如果一个项目做了一半一个人走了，接班的估计得从头开始设计；如<br />果需要在原来的版本基础上增加新功能，很可能也得从头来过，很难做到设计的可重用<br />性。<br />&nbsp; &nbsp; 在逻辑方面，我觉得比较重要的规范有这些：<br />&nbsp; &nbsp; 1.设计必须文档化。要将设计思路，详细实现等写入文档，然后经过严格评审通过<br />后才能进行下一步的工作。这样做乍看起来很花时间，但是从整个项目过程来看，绝对<br />要比一上来就写代码要节约时间，且这种做法可以使项目处于可控、可实现的状态。<br />&nbsp; &nbsp; 2.代码规范。<br />&nbsp; &nbsp; a.设计要参数化。比如一开始的设计时钟周期是30ns，复位周期是5个时钟周期，我<br />们可以这么写：<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; parameter&nbsp;&nbsp;CLK_PERIOD = 30;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; parameter&nbsp;&nbsp;RST_MUL_TIME = 5;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; parameter&nbsp;&nbsp;RST_TIME = RST_MUL_TIME * CLK_PERIOD;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; rst_n = 1'b0;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # RST_TIME rst_n = 1'b1;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # CLK_PERIOD/2 clk &lt;= ~clk;<br />&nbsp; &nbsp;&nbsp;&nbsp;如果在另一个设计中的时钟是40ns，复位周期不变，我们只需对CLK_PERIOD进行重<br />新例化就行了，从而使得代码更加易于重用。<br />&nbsp; &nbsp; b.信号命名要规范化。<br />&nbsp; &nbsp; 1) 信号名一律小写，参数用大写。<br />&nbsp; &nbsp; 2) 对于低电平有效的信号结尾要用_n标记，如rst_n。<br />&nbsp; &nbsp; 3) 端口信号排列要统一，一个信号只占一行，最好按输入输出及从哪个模块来到哪<br />个模块去的关系排列，这样在后期仿真<a href="#"><u><strong>验证</strong></u></a>找错时后&nbsp;&nbsp;方便很多。如：<br />&nbsp; &nbsp;&nbsp; &nbsp; module a(<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; //input<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; clk,<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; rst_n,&nbsp; &nbsp;//globle signal<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; wren,<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; rden,<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; avalon_din,&nbsp;&nbsp;//related to avalon bus<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; sdi,&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//related to serial port input<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; //output<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; data_ready,<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; avalon_dout, //related to avalon bus<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;);<br />&nbsp; &nbsp;&nbsp; &nbsp; 4) 一个模块尽量只用一个时钟，这里的一个模块是指一个module或者是一个en<br />tity。在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔<br />离。这样做可以让综合器综合出更优的结果。<br />&nbsp; &nbsp;&nbsp; &nbsp; 5) 尽量在底层模块上做逻辑，在高层尽量做例化，顶层模块只能做例化，禁止<br />出现任何胶连逻辑（glue logic），哪怕仅仅是对某个信号取反。理由同上。<br />&nbsp; &nbsp;&nbsp; &nbsp; 6) 在<a href="#"><u><strong>FPGA</strong></u></a>的设计上禁止用纯组合逻辑产生latch，带D触发器的latch的是允许的<br />，比如配置寄存器就是这种类型。<br />&nbsp; &nbsp;&nbsp; &nbsp; 7) 一般来说，进入FPGA的信号必须先同步，以提高系统工作频率（板级）。<br />&nbsp; &nbsp;&nbsp; &nbsp; 8) 所有模块的输出都要寄存器化，以提高工作频率，这对设计做到时序收敛也<br />是极有好处的。<br />&nbsp; &nbsp;&nbsp; &nbsp; 9) 除非是低功耗设计，不然不要用门控时钟--这会增加设计的不稳定性，在要<br />用到门控时钟的地方，也要将门控信号用时钟的下降沿 打一拍再输出与时钟相与。<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; clk_gate_en&nbsp; &nbsp;&nbsp; &nbsp;--------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;----<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;-----------------|D&nbsp; &nbsp;&nbsp;&nbsp;Q |------------------|&nbsp; &nbsp;&nbsp;&nbsp;\ gate_clk<br />_out<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;---------|&nbsp; &nbsp;&nbsp; &nbsp;)--------<br />-<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ------o|&gt;&nbsp; &nbsp;&nbsp; &nbsp; |&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp;&nbsp;/<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;clk&nbsp; &nbsp; |&nbsp; &nbsp;&nbsp; &nbsp; --------&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;|&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;----<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;------------------------------------<br />&nbsp; &nbsp;&nbsp; &nbsp; 10)禁止用计数器分频后的信号做其它模块的时钟，而要用改成时钟使能的方式<br />，否则这种时钟满天飞的方式对设计的可靠性极为不利，也大大增加了静态时序分析的<br />复杂性。如FPGA的输入时钟是25M的，现在系统内部要通过RS232与PC通信，要以rs232_<br />1xclk的速率发送数据。<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;不要这样做：<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;always (posedge rs232_1xclk or negedge rst_n)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;begin<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;end<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;而要这样做：<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;always (posedge clk_25m or negedge rst_n)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;begin<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; else if ( rs232_1xclk == 1'b1 )<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;end<br />&nbsp; &nbsp;&nbsp; &nbsp; 11)状态机要写成3段式的(这是最标准的写法)，即<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; always @(posedge clk or negedge rst_n)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;current_state &lt;= next_state;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; always @ (current_state ...)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; case(current_state)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; s1:<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; if ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;next_state = s2;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; always @(posedge clk or negedge rst_n)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;else<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;a &lt;= 1'b0;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;c &lt;= 1'b0;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;c &lt;= 1'b0;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//赋默认值<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;case(current_state)<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; s1:<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;a &lt;= 1'b0;&nbsp; &nbsp;//由于上面赋了默认值，这里就不用再对b<br />、c赋值了<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; s2:<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;b &lt;= 1'b1;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; s3:<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;c &lt;= 1'b1;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; default:<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; ...<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;...<br />&nbsp; &nbsp;&nbsp; &nbsp; 3.ALTERA参考设计准则<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;1) Ensure Clock, Preset, and Clear configurations are free of glitch<br />es.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2) Never use Clocks consisting of more than one level of combinatori<br />al logic.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;3) Carefully calculate setup times and hold times for multi-Clock sy<br />stems.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;4) Synchronize signals between flipflops in multi-Clock systems when<br />the setup and hold time requirements cannot be met.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;5) Ensure that Preset and Clear signals do not contain race conditio<br />ns.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;6) Ensure that no other internal race conditions exist.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;7) Register all glitch-sensitive outputs.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;8) Synchronize all asynchronous inputs.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;9) Never rely on delay chains for pin-to-pin or internal delays.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;10)Do not rely on Power-On Reset. Use a master Reset pin to clear al<br />l flipflops.<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;11)Remove any stuck states from state machines or synchronous logic.<br />&nbsp; &nbsp;&nbsp;&nbsp;其它方面的规范一时没有想到，想到了再写，也欢迎大家补充。<br /><br /><strong>３／如何提高电路工作频率</strong><br />&nbsp; &nbsp; 对于设计者来说，我们当然希望我们设计的电路的工作频率（在这里如无特别说明<br />，工作频率指FPGA片内的工作频率）尽量高。我们也经常听说用资源换速度，用流水的<br />方式可以提高工作频率，这确实是一个很重要的方法，今天我想进一步去分析该如何提<br />高电路的工作频率。<br />&nbsp; &nbsp; 我们先来分析下是什么影响了电路的工作频率。<br />&nbsp; &nbsp; 我们电路的工作频率主要与寄存器到寄存器之间的信号传播时延及clock skew有关<br />。在FPGA内部如果时钟走长线的话，clock skew很小，基本上可以忽略, 在这里为了简<br />单起见，我们只考虑信号的传播时延的因素。<br />&nbsp; &nbsp; 信号的传播时延包括寄存器的开关时延、走线时延、经过组合逻辑的时延（这样划<br />分或许不是很准确，不过对分析问题来说应该是没有可以的），要提高电路的工作频率<br />，我们就要在这三个时延中做文章，使其尽可能的小。<br />&nbsp; &nbsp; 我们先来看开关时延，这个时延是由器件物理特性决定的，我们没有办法去改变，<br />所以我们只能通过改变走线方式和减少组合逻辑的方法来提高工作频率。<br />&nbsp; &nbsp; 1.通过改变走线的方式减少时延。<br />&nbsp; &nbsp; 以altera的器件为例，我们在quartus里面的timing closure floorplan可以看到有<br />很多条条块块，我们可以将条条块块按行和按列分，每一个条块代表1个LAB，每个LAB里<br />有8个或者是10个LE。它们的走线时延的关系如下：同一个LAB中（最快） &lt; 同列或者同<br />行 &lt; 不同行且不同列。<br />&nbsp; &nbsp; 我们通过给综合器加适当的约束（不可贪心，一般以加5%裕量较为合适，比如电路<br />工作在100Mhz，则加约束加到105Mhz就可以了，贪心效果反而不好，且极大增加综合时<br />间）可以将相关的逻辑在布线时尽量布的靠近一点，从而减少走线的时延。（注：约束<br />的实现不完全是通过改进布局布线方式去提高工作频率，还有其它的改进措施）<br />&nbsp; &nbsp; 2.通过减少组合逻辑的减少时延。<br />&nbsp; &nbsp; 上面我们讲了可以通过加约束来提高工作频率，但是我们在做设计之初可万万不可<br />将提高工作频率的美好愿望寄托在加约束上，我们要通过合理的设计去避免出现大的组<br />合逻辑，从而提高电路的工作频率，这才能增强设计的可移植性，才可以使得我们的设<br />计在移植到另一同等速度级别的芯片时还能使用。<br />&nbsp; &nbsp; 我们知道，目前大部分FPGA都基于4输入LUT的，如果一个输出对应的判断条件大于<br />四输入的话就要由多个LUT级联才能完成，这样就引入一级组合逻辑时延，我们要减少组<br />合逻辑，无非就是要输入条件尽可能的少，，这样就可以级联的LUT更少，从而减少了组<br />合逻辑引起的时延。<br />&nbsp; &nbsp; 我们平时听说的流水就是一种通过切割大的组合逻辑（在其中插入一级或多级D触发<br />器，从而使寄存器与寄存器之间的组合逻辑减少）来提高工作频率的方法。比如一个32<br />位的计数器，该计数器的进位链很长，必然会降低工作频率，我们可以将其分割成4位和<br />8位的计数，每当4位的计数器计到15后触发一次8位的计数器，这样就实现了计数器的切<br />割，也提高了工作频率。<br />&nbsp; &nbsp; 在状态机中，一般也要将大的计数器移到状态机外，因为计数器这东西一般是经常<br />是大于4输入的，如果再和其它条件一起做为状态的跳变判据的话，必然会增加LUT的级<br />联，从而增大组合逻辑。以一个6输入的计数器为例，我们原希望当计数器计到111100后<br />状态跳变，现在我们将计数器放到状态机外，当计数器计到111011后产生个enable信号<br />去触发状态跳变，这样就将组合逻辑减少了。<br />&nbsp; &nbsp; 上面说的都是可以通过流水的方式切割组合逻辑的情况，但是有些情况下我们是很<br />难去切割组合逻辑的，在这些情况下我们又该怎么做呢？<br />&nbsp; &nbsp; 状态机就是这么一个例子，我们不能通过往状态译码组合逻辑中加入流水。如果我<br />们的设计中有一个几十个状态的状态机，它的状态译码逻辑将非常之巨大，毫无疑问，<br />这极有可能是设计中的关键路径。那我们该怎么做呢？还是老思路，减少组合逻辑。我<br />们可以对状态的输出进行分析，对它们进行重新分类，并根据这个重新定义成一组组小<br />状态机，通过对输入进行选择(case语句)并去触发相应的小状态机，从而实现了将大的<br />状态机切割成小的状态机。在ATA6的规范中（硬盘的标准），输入的命令大概有20十种<br />，每一个命令又对应很多种状态，如果用一个大的状态机（状态套状态）去做那是不可<br />想象的，我们可以通过case语句去对命令进行译码，并触发相应的状态机，这样做下来<br />这一个模块的频率就可以跑得比较高了。<br />&nbsp; &nbsp; 总结：提高工作频率的本质就是要减少寄存器到寄存器的时延，最有效的方法就是<br />避免出现大的组合逻辑，也就是要尽量去满足四输入的条件，减少LUT级联的数量。我们<br />可以通过加约束、流水、切割状态的方法提高工作频率。<br /><br />４／　做逻辑的难点在于系统结构设计和仿真验证<br />&nbsp; &nbsp; 刚去公司的时候BOSS就和我讲，做逻辑的难点不在于RTL级代码的设计，而在于系统<br />结构设计和仿真验证方面。目前国内对可综合的设计强调的比较多，而对系统结构设计<br />和仿真验证方面似乎还没有什么资料，这或许也从一个侧面反映了国内目前的设计水平<br />还比较低下吧。<br />&nbsp; &nbsp; 以前在学校的时候，总是觉得将RTL级代码做好就行了，仿真验证只是形式而已，所<br />以对HDL的行为描述方面的语法不屑一顾，对testbench也一直不愿意去学--因为觉得画<br />波形图方便；对于系统结构设计更是一点都不懂了。<br />&nbsp; &nbsp; 到了公司接触了些东西才发现完全不是这样。<br />&nbsp; &nbsp; 其实在国外，花在仿真验证上的时间和人力大概是花在RTL级代码上的两倍，现在仿<br />真验证才是百万门级芯片设计的关键路径。仿真验证的难点主要在于怎么建模才能完全<br />和准确地去验证设计的正确性（主要是提高代码覆盖），在这过程中，验证速度也是很<br />重要的。<br />&nbsp; &nbsp; 验证说白了也就是怎么产生足够覆盖率的激励源，然后怎么去检测错误。我个人认<br />为，在仿真验证中，最基本就是要做到验证的自动化。这也是为什么我们要写testbenc<br />h的原因。在我现在的一个设计中，每次跑仿真都要一个小时左右（这其实算小设计）。<br />由于画波形图无法做到验证自动化，如果用通过画波形图来仿真的话，一是画波形会画<br />死（特别是对于算法复杂的、输入呈统计分布的设计），二是看波形图要看死，三是检<br />错率几乎为零。<br />&nbsp; &nbsp; 那么怎么做到自动化呢？我个人的水平还很有限，只能简单地谈下BFM（bus funct<br />ion model，总线功能模型）。<br />&nbsp; &nbsp; 以做一个MAC的core为例（背板是PCI总线），那么我们需要一个MAC_BFM和PCI_BFM<br />及PCI_BM（PCI behavior model）。MAC_BFM的主要功能是产生以太网帧(激励源），随<br />机的长度和帧头，内容也是随机的,在发送的同时也将其复制一份到PCI_BM中；PCI_BFM<br />的功能则是仿PCI总线的行为，比如被测收到了一个正确帧后会向PCI总线发送一个<br />请求，PCI_BFM则会去响应它，并将数据收进来；PCI_BM的主要功能是将MAC_BFM发送出<br />来的东西与PCI_BFM接收到的东西做比较，由于它具有了MAC_BFM的发送信息和PCI_BFM的<br />接收信息，只要设计合理，它总是可以自动地、完全地去测试被测是否工作正常，<br />从而实现自动检测。<br />&nbsp; &nbsp; 华为在仿真验证方面估计在国内来说是做的比较好的，他们已建立起了比较好的验<br />证平台，大部分与通信有关的BFM都做好了，听我朋友说，现在他们只需要将被测放<br />在测试平台中，并配置好参数，就可以自动地检测被测功能的正确与否。<br />&nbsp; &nbsp; 在功能仿真做完后，由于我们做在是FPGA的设计，在设计时已经基本保证RTL级代码<br />在综合结果和功能仿真结果的一致性，只要综合布局布线后的静态时序报告没有违反时<br />序约束的警告，就可以下到板子上去调试了。事实上，在华为中兴，他们做FPGA的设计<br />时也是不做时序仿真的，因为做时序仿真很花时间，且效果也不见得比看静态时序分析<br />报告好。<br />&nbsp; &nbsp; 当然了，如果是<a href="#"><u><strong>ASIC</strong></u></a>的设计话，它们的仿真验证的工作量要大一些，在涉及到多时<br />钟域的设计时，一般还是做后仿的。不过在做后仿之前，也一般会先用形式验证工具和<br />通过静态时序分序报告去查看有没有违反设计要求的地方，这样做了之后，后仿的工作<br />量可以小很多。<br />&nbsp; &nbsp; 在<a href="#"><u><strong>HDL语言</strong></u></a>方面，国内语言很多人都在争论<a href="#"><u><strong>VHDL</strong></u></a>和<a href="#"><u><strong>verilog</strong></u></a>哪个好，其实我个人认为<br />这并没有多大的意义，外面的大公司基本上都是用verilog在做RTL级的代码，所以还是<br />建议大家尽量学verilog。在仿真方面，由于VHDL在行为级建模方面弱于verilog，用VH<br />DL做仿真模型的很少，当然也不是说verilog就好，其实verilog在复杂的行为级建模方<br />面的能力也是有限的，比如目前它还不支持数组。在一些复杂的算法设计中，需要高级<br />语言做抽象才能描述出行为级模型。在国外，仿真建模很多都是用System C和E语言，用<br />verilog的都算是很落后的了，国内华为的验证平台好像是用System C写。<br />&nbsp; &nbsp; 在系统结构设计方面，由于我做的设计还不够大，还谈不上什么经验，只是觉得必<br />须要具备一些计算机系统结构的知识才行。划分的首要依据是功能，之后是选择合适的<br />总线结构、存储结构和处理器架构，通过系统结构划分要使各部分功能模块清晰，易于<br />实现。这一部分我想过段时间有一点体会了再和大家分享，就先不误导大家了。<br /></p>]]></description>
		</item>
		    
		
		<item>
			<title>quartus中LMP 总结（原创）</title>
			<link>http://hellboy158.blog.sohu.com/57643482.html</link>
			<comments>http://hellboy158.blog.sohu.com/57643482.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 31 Jul 2007 13:40:02 +0800</pubDate>
			<guid>http://hellboy158.blog.sohu.com/57643482.html</guid>
			<description><![CDATA[<p><font size="3"><font size="4">Gate Function</font><br />LPM_and&nbsp;&nbsp; &nbsp; :&nbsp;可编程的按位做与运算的与门<br />LPM_bustri&nbsp; ：可编程的三态门（可单向，也可双向）<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enabletr(高电平有效)使能tridata =&gt; result<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enabledt(高电平有效)使能data =&gt; tridata<br />LPM_clshift&nbsp;:&nbsp;可编程的组合逻辑移位器。方向和距离是可以编程的。<br />LPM_constant:&nbsp;可编程常数生成器<br />LPM_decode&nbsp; : 可编程译码器<br />LPM_inv&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程反向器(位数可控)<br />LPM_mux&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程多路选择器(sel选择哪路输出)<br />busmus&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程2路选择器(LPM_mux的特殊情况)<br />mux&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程多路选择器,只有一位输出结果(LPM_mux的宽度为1)<br />LPM_or&nbsp;&nbsp; &nbsp;&nbsp; :&nbsp;可编程的按位做或运算的或门<br />LPM_xor&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程的按位做异或运算的异或门</font></p>
<p><font size="4">Arithmetic Funtions</font></p>
<p><font size="3">LMP_abs&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;求绝对值(如果data = 1000000,overflow=1)<br />LPM_add_sub&nbsp;:&nbsp;可编程加减法器(可以由管脚决定)<br />LPM_compare&nbsp;:&nbsp;可编程的比较器(可以设定各种输出)<br />LPM_counter&nbsp;:&nbsp;可编程计数器<br />LPM_mult&nbsp;&nbsp;&nbsp; :&nbsp;可编程乘法器<br />LPM_divide&nbsp; :&nbsp;可编程除法器<br />divide&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;可编程除法器（与LPM_divide没有什么区别）<br />Parallel_add&nbsp; :&nbsp;可编程多路并行加法器<br />altmult_accum&nbsp;:&nbsp;可编程乘加器<br />altaccumulate&nbsp;: 可编程累加器<br />altmemmult&nbsp;&nbsp;&nbsp; :&nbsp;</font></p>
<p><font size="3">&nbsp;<br /><font size="4">Storage Functions&nbsp;</font></font></p>
<p><font size="3">LPM_ff&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程的触发器(D触发器或T触发器)&nbsp;<br />LPM_latch&nbsp; :&nbsp;可编程的锁存器(gate=0锁存)<br />LPM_ram_dq&nbsp;:&nbsp;可编程的同步或异步单端口RAM(两套地址线).<br />LPM_ram_dp&nbsp;:&nbsp;可编程的简单双端口和真正双端口RAM().<br />LPM_ram_io&nbsp;:&nbsp;可编程的RAM（地址线一套，数据线为双向的IO）<br />LPM_rom&nbsp;&nbsp;&nbsp; :&nbsp;可编程的ROM<br />LPM_shiftreg&nbsp;:&nbsp;可编程的移位寄存器<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /><font size="4">Custom Parameterized Functions</font></font></p>
<p><font size="3">csfifo&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;可编程的FIFO<br />csdpram&nbsp;&nbsp;&nbsp; :&nbsp;可编程的双口RAM&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>]]></description>
		</item>
		    
		
		<item>
			<title>上拉电阻下拉电阻的总结--转贴</title>
			<link>http://hellboy158.blog.sohu.com/57640311.html</link>
			<comments>http://hellboy158.blog.sohu.com/57640311.html#comment</comments>
			<dc:creator>地狱男孩</dc:creator>
			<pubDate>Tue, 31 Jul 2007 11:10:30 +0800</pubDate>
			<guid>http://hellboy158.blog.sohu.com/57640311.html</guid>
			<description><![CDATA[<div>&nbsp;</div>
<table style="TABLE-LAYOUT: fixed">
<tbody>
<tr>
<td>
<div>
<p align="left"><strong><span style="FONT-SIZE: 11pt; COLOR: black">上拉电阻下拉电阻的总结</span></strong><strong><span style="FONT-SIZE: 11pt; COLOR: black"></span></strong></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black">注：部分内容不准确，请注意</span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black">上拉电阻：</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />1</span><span style="FONT-SIZE: 9pt; COLOR: black">、当</span><span style="FONT-SIZE: 9pt; COLOR: black">TTL</span><span style="FONT-SIZE: 9pt; COLOR: black">电路驱动</span><span style="FONT-SIZE: 9pt; COLOR: black">COMS</span><span style="FONT-SIZE: 9pt; COLOR: black">电路时，如果</span><span style="FONT-SIZE: 9pt; COLOR: black">TTL</span><span style="FONT-SIZE: 9pt; COLOR: black">电路输出的高电平低于</span><span style="FONT-SIZE: 9pt; COLOR: black">COMS</span><span style="FONT-SIZE: 9pt; COLOR: black">电路的最低高电平（一般为</span><span style="FONT-SIZE: 9pt; COLOR: black">3.5V</span><span style="FONT-SIZE: 9pt; COLOR: black">），这时就需要在</span><span style="FONT-SIZE: 9pt; COLOR: black">TTL</span><span style="FONT-SIZE: 9pt; COLOR: black">的输出端接上拉电阻，以提高输出高电平的值。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />2</span><span style="FONT-SIZE: 9pt; COLOR: black">、</span><span style="FONT-SIZE: 9pt; COLOR: black">OC</span><span style="FONT-SIZE: 9pt; COLOR: black">门电路必须加上拉电阻，才能使用。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />3</span><span style="FONT-SIZE: 9pt; COLOR: black">、为加大输出引脚的驱动能力，有的<a href="file::;"><u><strong>单片机</strong></u></a>管脚上也常使用上拉电阻。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />4</span><span style="FONT-SIZE: 9pt; COLOR: black">、在</span><span style="FONT-SIZE: 9pt; COLOR: black">COMS</span><span style="FONT-SIZE: 9pt; COLOR: black">芯片上，为了防止静电造成损坏，不用的管脚不能悬空，一般接上拉电阻产生降低输入阻抗，提供泄荷通路。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />5</span><span style="FONT-SIZE: 9pt; COLOR: black">、芯片的管脚加上拉电阻来提高输出电平，从而提高芯片输入信号的噪声容限增强抗干扰能力。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />6</span><span style="FONT-SIZE: 9pt; COLOR: black">、提高总线的抗电磁干扰能力。管脚悬空就比较容易接受外界的电磁干扰。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />7</span><span style="FONT-SIZE: 9pt; COLOR: black">、长线传输中电阻不匹配容易引起反射波干扰，加上下拉电阻是电阻匹配，有效的抑制反射波干扰。</span><span style="FONT-SIZE: 9pt; COLOR: black"></span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black">上拉电阻阻值的选择原则包括</span><span style="FONT-SIZE: 9pt; COLOR: black">:<br />1</span><span style="FONT-SIZE: 9pt; COLOR: black">、从节约功耗及芯片的灌电流能力考虑应当足够大；电阻大，电流小。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />2</span><span style="FONT-SIZE: 9pt; COLOR: black">、从确保足够的驱动电流考虑应当足够小；电阻小，电流大。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />3</span><span style="FONT-SIZE: 9pt; COLOR: black">、对于高速电路，过大的上拉电阻可能边沿变平缓。综合考虑以上三点</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">通常在</span><span style="FONT-SIZE: 9pt; COLOR: black">1k</span><span style="FONT-SIZE: 9pt; COLOR: black">到</span><span style="FONT-SIZE: 9pt; COLOR: black">10k</span><span style="FONT-SIZE: 9pt; COLOR: black">之间选取。对下拉电阻也有类似道理。</span><span style="FONT-SIZE: 9pt; COLOR: black"></span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black">对上拉电阻和下拉电阻的选择应结合开关管特性和下级电路的输入特性进行设定，主要需要考虑以下几个因素：</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />1</span><span style="FONT-SIZE: 9pt; COLOR: black">．</span><span style="FONT-SIZE: 9pt; COLOR: black"> </span><span style="FONT-SIZE: 9pt; COLOR: black">驱动能力与功耗的平衡。以上拉电阻为例，一般地说，上拉电阻越小，驱动能力越强，但功耗越大，设计是应注意两者之间的均衡。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />2</span><span style="FONT-SIZE: 9pt; COLOR: black">．</span><span style="FONT-SIZE: 9pt; COLOR: black"> </span><span style="FONT-SIZE: 9pt; COLOR: black">下级电路的驱动需求。同样以上拉电阻为例，当输出高电平时，开关管断开，上拉电阻应适当选择以能够向下级电路提供足够的电流。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />3</span><span style="FONT-SIZE: 9pt; COLOR: black">．</span><span style="FONT-SIZE: 9pt; COLOR: black"> </span><span style="FONT-SIZE: 9pt; COLOR: black">高低电平的设定。不同电路的高低电平的门槛电平会有不同，电阻应适当设定以确保能输出正确的电平。以上拉电阻为例，当输出低电平时，开关管导通，上拉电阻和开关管导通电阻分压值应确保在零电平门槛之下。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />4</span><span style="FONT-SIZE: 9pt; COLOR: black">．</span><span style="FONT-SIZE: 9pt; COLOR: black"> </span><span style="FONT-SIZE: 9pt; COLOR: black">频率特性。以上拉电阻为例，上拉电阻和开关管漏源级之间的电容和下级电路之间的输入电容会形成</span><span style="FONT-SIZE: 9pt; COLOR: black">RC</span><span style="FONT-SIZE: 9pt; COLOR: black">延迟，电阻越大，延迟越大。上拉电阻的设定应考虑电路在这方面的需求。</span><span style="FONT-SIZE: 9pt; COLOR: black"></span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black">下拉电阻的设定的原则和上拉电阻是一样的。</span><span style="FONT-SIZE: 9pt; COLOR: black"></span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black"><br />OC</span><span style="FONT-SIZE: 9pt; COLOR: black">门输出高电平时是一个高阻态，其上拉电流要由上拉电阻来提供，设输入端每端口不大于</span><span style="FONT-SIZE: 9pt; COLOR: black">100uA,</span><span style="FONT-SIZE: 9pt; COLOR: black">设输出口驱动电流约</span><span style="FONT-SIZE: 9pt; COLOR: black">500uA</span><span style="FONT-SIZE: 9pt; COLOR: black">，标准工作电压是</span><span style="FONT-SIZE: 9pt; COLOR: black">5V</span><span style="FONT-SIZE: 9pt; COLOR: black">，输入口的高低电平门限为</span><span style="FONT-SIZE: 9pt; COLOR: black">0.8V(</span><span style="FONT-SIZE: 9pt; COLOR: black">低于此值为低电平</span><span style="FONT-SIZE: 9pt; COLOR: black">)</span><span style="FONT-SIZE: 9pt; COLOR: black">；</span><span style="FONT-SIZE: 9pt; COLOR: black">2V(</span><span style="FONT-SIZE: 9pt; COLOR: black">高电平门限值</span><span style="FONT-SIZE: 9pt; COLOR: black">)</span><span style="FONT-SIZE: 9pt; COLOR: black">。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black">选上拉电阻时：</span><span style="FONT-SIZE: 9pt; COLOR: black"><br />500uA x 8.4K= 4.2</span><span style="FONT-SIZE: 9pt; COLOR: black">即选大于</span><span style="FONT-SIZE: 9pt; COLOR: black">8.4K</span><span style="FONT-SIZE: 9pt; COLOR: black">时输出端能下拉至</span><span style="FONT-SIZE: 9pt; COLOR: black">0.8V</span><span style="FONT-SIZE: 9pt; COLOR: black">以下，此为最小阻值，再小就拉不下来了。如果输出口驱动电流较大，则阻值可减小，保证下拉时能低于</span><span style="FONT-SIZE: 9pt; COLOR: black">0.8V</span><span style="FONT-SIZE: 9pt; COLOR: black">即可。</span><span style="FONT-SIZE: 9pt; COLOR: black"><br /></span><span style="FONT-SIZE: 9pt; COLOR: black">当输出高电平时，忽略管子的漏电流，两输入口需</span><span style="FONT-SIZE: 9pt; COLOR: black">200uA 200uA x15K=3V</span><span style="FONT-SIZE: 9pt; COLOR: black">即上拉电阻压降为</span><span style="FONT-SIZE: 9pt; COLOR: black">3V</span><span style="FONT-SIZE: 9pt; COLOR: black">，输出口可达到</span><span style="FONT-SIZE: 9pt; COLOR: black">2V</span><span style="FONT-SIZE: 9pt; COLOR: black">，此阻值为最大阻值，再大就拉不到</span><span style="FONT-SIZE: 9pt; COLOR: black">2V</span><span style="FONT-SIZE: 9pt; COLOR: black">了。选</span><span style="FONT-SIZE: 9pt; COLOR: black">10K</span><span style="FONT-SIZE: 9pt; COLOR: black">可用。</span><span style="FONT-SIZE: 9pt; COLOR: black">COMS</span><span style="FONT-SIZE: 9pt; COLOR: black">门的可参考</span><span style="FONT-SIZE: 9pt; COLOR: black">74HC</span><span style="FONT-SIZE: 9pt; COLOR: black">系列，设计时管子的漏电流不可忽略，</span><span style="FONT-SIZE: 9pt; COLOR: black">IO</span><span style="FONT-SIZE: 9pt; COLOR: black">口实际电流在不同电平下也是不同的，上述仅仅是原理，一句话概括为：输出高电平时要喂饱后面的输入口，输出低电平不要把输出口喂撑了（否则多余的电流喂给了级联的输入口，高于低电平门限值就不可靠了）。</span><span style="FONT-SIZE: 9pt; COLOR: black"></span></p>
<p align="left"><span style="FONT-SIZE: 9pt; COLOR: black">在数字电路中不用的输入脚都要接固定电平，通过</span><span style="FONT-SIZE: 9pt; COLOR: black">1k</span><span style="FONT-SIZE: 9pt; COLOR: black">电阻接高电平或接地。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />1. </span><span style="FONT-SIZE: 9pt; COLOR: black">电阻作用：</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">接电组就是为了防止输入端悬空</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">减弱外部电流对芯片产生的干扰</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">保护</span><span style="FONT-SIZE: 9pt; COLOR: black">cmos</span><span style="FONT-SIZE: 9pt; COLOR: black">内的保护二极管</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">一般电流不大于</span><span style="FONT-SIZE: 9pt; COLOR: black">10mA <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">上拉和下拉、限流</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />&nbsp;&nbsp; 1. </span><span style="FONT-SIZE: 9pt; COLOR: black">改变电平的电位，常用在</span><span style="FONT-SIZE: 9pt; COLOR: black">TTL-CMOS</span><span style="FONT-SIZE: 9pt; COLOR: black">匹配</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />&nbsp;&nbsp; 2. </span><span style="FONT-SIZE: 9pt; COLOR: black">在引脚悬空时有确定的状态</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />&nbsp;&nbsp; 3. </span><span style="FONT-SIZE: 9pt; COLOR: black">增加高电平输出时的驱动能力。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />&nbsp;&nbsp; 4</span><span style="FONT-SIZE: 9pt; COLOR: black">、为</span><span style="FONT-SIZE: 9pt; COLOR: black">OC</span><span style="FONT-SIZE: 9pt; COLOR: black">门提供电流</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">那要看输出口驱动的是什么器件，如果该器件需要高电压的话，而输出口的输出电压又不够，就需要加上拉电阻。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">如果有上拉电阻那它的端口在默认值为高电平你要控制它必须用低电平才能控制如三态门电路三极管的集电极，或二极管正极去控制把上拉电阻的电流拉下来成为低电平。反之，</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">尤其用在接口电路中</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">为了得到确定的电平</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">一般采用这种方法</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">以保证正确的电路状态</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">以免发生意外</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">比如</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">在电机控制中</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">逆变桥上下桥臂不能直通</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">如果它们都用同一个单片机来驱动</span><span style="FONT-SIZE: 9pt; COLOR: black">,</span><span style="FONT-SIZE: 9pt; COLOR: black">必须设置初始状态</span><span style="FONT-SIZE: 9pt; COLOR: black">.</span><span style="FONT-SIZE: 9pt; COLOR: black">防止直通</span><span style="FONT-SIZE: 9pt; COLOR: black">! <br /><br />2</span><span style="FONT-SIZE: 9pt; COLOR: black">、定义：</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">上拉就是将不确定的信号通过一个电阻嵌位在高电平！电阻同时起限流作用！下拉同理！</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">上拉是对器件注入电流，下拉是输出电流</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">弱强只是上拉电阻的阻值不同，没有什么严格区分</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">对于非集电极（或漏极）开路输出型电路（如普通门电路）提升电流和电压的能力是有限的，上拉电阻的功能主要是为集电极开路输出型电路输出电流通道。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br /><br />3</span><span style="FONT-SIZE: 9pt; COLOR: black">、为什么要使用拉电阻：</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">一般作单键触发使用时，如果</span><span style="FONT-SIZE: 9pt; COLOR: black">IC</span><span style="FONT-SIZE: 9pt; COLOR: black">本身没有内接电阻，为了使单键维持在不被触发的状态或是触发后回到原状态，必须在</span><span style="FONT-SIZE: 9pt; COLOR: black">IC</span><span style="FONT-SIZE: 9pt; COLOR: black">外部另接一电阻。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">数字电路有三种状态：高电平、低电平、和高阻状态，有些应用场合不希望出现高阻状态，可以通过上拉电阻或下拉电阻的方式使处于稳定状态，具体视设计要求而定！</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">一般说的是</span><span style="FONT-SIZE: 9pt; COLOR: black">I/O</span><span style="FONT-SIZE: 9pt; COLOR: black">端口，有的可以设置，有的不可以设置，有的是内置，有的是需要外接，</span><span style="FONT-SIZE: 9pt; COLOR: black">I/O</span><span style="FONT-SIZE: 9pt; COLOR: black">端口的输出类似与一个三极管的</span><span style="FONT-SIZE: 9pt; COLOR: black">C</span><span style="FONT-SIZE: 9pt; COLOR: black">，当</span><span style="FONT-SIZE: 9pt; COLOR: black">C</span><span style="FONT-SIZE: 9pt; COLOR: black">接通过一个电阻和电源连接在一起的时候，该电阻成为上</span><span style="FONT-SIZE: 9pt; COLOR: black">C</span><span style="FONT-SIZE: 9pt; COLOR: black">拉电阻，也就是说，如果该端口正常时为高电平，</span><span style="FONT-SIZE: 9pt; COLOR: black">C</span><span style="FONT-SIZE: 9pt; COLOR: black">通过一个电阻和地连接在一起的时候，该电阻称为下拉电阻，使该端口平时为低电平，作用吗：</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br /></span><span style="FONT-SIZE: 9pt; COLOR: black">比如：当一个接有上拉电阻的端口设为输如状态时，他的常态就为高电平，用于检测低电平的输入。</span><span style="FONT-SIZE: 9pt; COLOR: black"> <br />l </span><span style="FONT-SIZE: 9pt; COLOR: black">上拉电阻是用来解决总线驱动能力不足时提供电流的。一般说法是拉电流，下拉电阻是用来吸收电流的。</span></p></div></td></tr></tbody></table>]]></description>
		</item>
		    
		
	</channel>
</rss>
