在公司里的几个月,做的项目其实不多,但是收获还是有一些,我觉得收获最大的是
设计理念的改变,这也是我这段时间最想总结的,我会在后面逐渐阐述。
1 时序是设计出来的
我的boss有在华为及峻龙工作的背景,自然就给我们讲了一些华为及altera做逻辑
的一些东西,而我们的项目规范,也基本上是按华为的那一套去做。在工作这几个月中
,给我感触最深的是华为的那句话:时序是设计出来的,不是仿出来的,更不是湊出来
的。
在我们公司,每一个项目都有很严格的评审,只有评审通过了,才能做下一步的工
作。以做逻辑为例,并不是一上来就开始写代码,而是要先写总体设计方案和逻辑详细
设计方案,要等这些方案评审通过,认为可行了,才能进行编码,一般来说这部分工作
所占的时间要远大于编码的时间。
总体方案主要是涉及模块划分,一级模块和二级模块的接口信号和时序(我们要求
把接口信号的时序波形描述出来)以及将来如何测试设计。在这一级方案中,要保证在
今后的设计中时序要收敛到一级模块(最后是在二级模块中)。什么意思呢?我们在做
详细设计的时候,对于一些信号的时序肯定会做一些调整的,但是这种时序的调整最多
只能波及到本一级模块,而不能影响到整个设计。记得以前在学校做设计的时候,由于
不懂得设计时序,经常因为有一处信号的时序不满足,结果不得不将其它模块信号的时
序也改一下,搞得人很郁闷。
在逻辑详细设计方案这一级的时候,我们已经将各级模块的接口时序都设计出来了
,各级模块内部是怎么实现的也基本上确定下来了。
由于做到这一点,在编码的时候自然就很快了,最重要的是这样做后可以让设计会
一直处于可控的状态,不会因为某一处的错误引起整个设计从头进行。
2规范很重要
工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件软件
还是硬件),不按照规范走几乎是不可实现的。逻辑设计也是这样:如果不按规范做的
话,过一个月后调试时发现有错,回头再看自己写的代码,估计很多信号功能都忘了,
更不要说检错了;如果一个项目做了一半一个人走了,接班的估计得从头开始设计;如
果需要在原来的版本基础上增加新功能,很可能也得从头来过,很难做到设计的可重用
性。
在逻辑方面,我觉得比较重要的规范有这些:
1.设计必须文档化。要将设计思路,详细实现等写入文档,然后经过严格评审通过
后才能进行下一步的工作。这样做乍看起来很花时间,但是从整个项目过程来看,绝对
要比一上来就写代码要节约时间,且这种做法可以使项目处于可控、可实现的状态。
2.代码规范。
a.设计要参数化。比如一开始的设计时钟周期是30ns,复位周期是5个时钟周期,我
们可以这么写:
parameter CLK_PERIOD = 30;
parameter RST_MUL_TIME = 5;
parameter RST_TIME = RST_MUL_TIME * CLK_PERIOD;
...
rst_n = 1'b0;
# RST_TIME rst_n = 1'b1;
...
# CLK_PERIOD/2 clk <= ~clk;
如果在另一个设计中的时钟是40ns,复位周期不变,我们只需对CLK_PERIOD进行重
新例化就行了,从而使得代码更加易于重用。
b.信号命名要规范化。
1) 信号名一律小写,参数用大写。
2) 对于低电平有效的信号结尾要用_n标记,如rst_n。
3) 端口信号排列要统一,一个信号只占一行,最好按输入输出及从哪个模块来到哪
个模块去的关系排列,这样在后期仿真验证验证找错时后 方便很多。如:
module a(
//input
clk,
rst_n, //globle signal
wren,
rden,
avalon_din, //related to avalon bus
sdi, //related to serial port input
//output
data_ready,
avalon_dout, //related to avalon bus
...
);
4) 一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个en
tity。在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔
离。这样做可以让综合器综合出更优的结果。
5) 尽量在底层模块上做逻辑,在高层尽量做例化,顶层模块只能做例化,禁止
出现任何胶连逻辑(glue logic),哪怕仅仅是对某个信号取反。理由同上。
6) 在FPGAFPGA的设计上禁止用纯组合逻辑产生latch,带D触发器的latch的是允许的
,比如配置寄存器就是这种类型。
7) 一般来说,进入FPGA的信号必须先同步,以提高系统工作频率(板级)。
8) 所有模块的输出都要寄存器化,以提高工作频率,这对设计做到时序收敛也
是极有好处的。
9) 除非是低功耗设计,不然不要用门控时钟--这会增加设计的不稳定性,在要
用到门控时钟的地方,也要将门控信号用时钟的下降沿 打一拍再输出与时钟相与。
clk_gate_en -------- ----
-----------------|D Q |------------------| \ gate_clk
_out
| | ---------| )--------
-
------o|> | | | /
clk | -------- | ----
------------------------------------
10)禁止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式
,否则这种时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的
复杂性。如FPGA的输入时钟是25M的,现在系统内部要通过RS232与PC通信,要以rs232_
1xclk的速率发送数据。
不要这样做:
always (posedge rs232_1xclk or negedge rst_n)
begin
...
end
而要这样做:
always (posedge clk_25m or negedge rst_n)
begin
...
else if ( rs232_1xclk == 1'b1 )
...
end
11)状态机要写成3段式的(这是最标准的写法),即
...
always @(posedge clk or negedge rst_n)
...
current_state <= next_state;
...
always @ (current_state ...)
...
case(current_state)
...
s1:
if ...
next_state = s2;
...
...
always @(posedge clk or negedge rst_n)
...
else
a <= 1'b0;
c <= 1'b0;
c <= 1'b0; //赋默认值
case(current_state)
s1:
a <= 1'b0; //由于上面赋了默认值,这里就不用再对b
、c赋值了
s2:
b <= 1'b1;
s3:
c <= 1'b1;
default:
...
...
3.ALTERA参考设计准则
1) Ensure Clock, Preset, and Clear configurations are free of glitch
es.
2) Never use Clocks consisting of more than one level of combinatori
al logic.
3) Carefully calculate setup times and hold times for multi-Clock sy
stems.
4) Synchronize signals between flipflops in multi-Clock systems when
the setup and hold time requirements cannot be met.
5) Ensure that Preset and Clear signals do not contain race conditio
ns.
6) Ensure that no other internal race conditions exist.
7) Register all glitch-sensitive outputs.
8) Synchronize all asynchronous inputs.
9) Never rely on delay chains for pin-to-pin or internal delays.
10)Do not rely on Power-On Reset. Use a master Reset pin to clear al
l flipflops.
11)Remove any stuck states from state machines or synchronous logic.
其它方面的规范一时没有想到,想到了再写,也欢迎大家补充。
3/如何提高电路工作频率
对于设计者来说,我们当然希望我们设计的电路的工作频率(在这里如无特别说明
,工作频率指FPGA片内的工作频率)尽量高。我们也经常听说用资源换速度,用流水的
方式可以提高工作频率,这确实是一个很重要的方法,今天我想进一步去分析该如何提
高电路的工作频率。
我们先来分析下是什么影响了电路的工作频率。
我们电路的工作频率主要与寄存器到寄存器之间的信号传播时延及clock skew有关
。在FPGA内部如果时钟走长线的话,clock skew很小,基本上可以忽略, 在这里为了简
单起见,我们只考虑信号的传播时延的因素。
信号的传播时延包括寄存器的开关时延、走线时延、经过组合逻辑的时延(这样划
分或许不是很准确,不过对分析问题来说应该是没有可以的),要提高电路的工作频率
,我们就要在这三个时延中做文章,使其尽可能的小。
我们先来看开关时延,这个时延是由器件物理特性决定的,我们没有办法去改变,
所以我们只能通过改变走线方式和减少组合逻辑的方法来提高工作频率。
1.通过改变走线的方式减少时延。
以altera的器件为例,我们在quartus里面的timing closure floorplan可以看到有
很多条条块块,我们可以将条条块块按行和按列分,每一个条块代表1个LAB,每个LAB里
有8个或者是10个LE。它们的走线时延的关系如下:同一个LAB中(最快) < 同列或者同
行 < 不同行且不同列。
我们通过给综合器加适当的约束(不可贪心,一般以加5%裕量较为合适,比如电路
工作在100Mhz,则加约束加到105Mhz就可以了,贪心效果反而不好,且极大增加综合时
间)可以将相关的逻辑在布线时尽量布的靠近一点,从而减少走线的时延。(注:约束
的实现不完全是通过改进布局布线方式去提高工作频率,还有其它的改进措施)
2.通过减少组合逻辑的减少时延。
上面我们讲了可以通过加约束来提高工作频率,但是我们在做设计之初可万万不可
将提高工作频率的美好愿望寄托在加约束上,我们要通过合理的设计去避免出现大的组
合逻辑,从而提高电路的工作频率,这才能增强设计的可移植性,才可以使得我们的设
计在移植到另一同等速度级别的芯片时还能使用。
我们知道,目前大部分FPGA都基于4输入LUT的,如果一个输出对应的判断条件大于
四输入的话就要由多个LUT级联才能完成,这样就引入一级组合逻辑时延,我们要减少组
合逻辑,无非就是要输入条件尽可能的少,,这样就可以级联的LUT更少,从而减少了组
合逻辑引起的时延。
我们平时听说的流水就是一种通过切割大的组合逻辑(在其中插入一级或多级D触发
器,从而使寄存器与寄存器之间的组合逻辑减少)来提高工作频率的方法。比如一个32
位的计数器,该计数器的进位链很长,必然会降低工作频率,我们可以将其分割成4位和
8位的计数,每当4位的计数器计到15后触发一次8位的计数器,这样就实现了计数器的切
割,也提高了工作频率。
在状态机中,一般也要将大的计数器移到状态机外,因为计数器这东西一般是经常
是大于4输入的,如果再和其它条件一起做为状态的跳变判据的话,必然会增加LUT的级
联,从而增大组合逻辑。以一个6输入的计数器为例,我们原希望当计数器计到111100后
状态跳变,现在我们将计数器放到状态机外,当计数器计到111011后产生个enable信号
去触发状态跳变,这样就将组合逻辑减少了。
上面说的都是可以通过流水的方式切割组合逻辑的情况,但是有些情况下我们是很
难去切割组合逻辑的,在这些情况下我们又该怎么做呢?
状态机就是这么一个例子,我们不能通过往状态译码组合逻辑中加入流水。如果我
们的设计中有一个几十个状态的状态机,它的状态译码逻辑将非常之巨大,毫无疑问,
这极有可能是设计中的关键路径。那我们该怎么做呢?还是老思路,减少组合逻辑。我
们可以对状态的输出进行分析,对它们进行重新分类,并根据这个重新定义成一组组小
状态机,通过对输入进行选择(case语句)并去触发相应的小状态机,从而实现了将大的
状态机切割成小的状态机。在ATA6的规范中(硬盘的标准),输入的命令大概有20十种
,每一个命令又对应很多种状态,如果用一个大的状态机(状态套状态)去做那是不可
想象的,我们可以通过case语句去对命令进行译码,并触发相应的状态机,这样做下来
这一个模块的频率就可以跑得比较高了。
总结:提高工作频率的本质就是要减少寄存器到寄存器的时延,最有效的方法就是
避免出现大的组合逻辑,也就是要尽量去满足四输入的条件,减少LUT级联的数量。我们
可以通过加约束、流水、切割状态的方法提高工作频率。
4/ 做逻辑的难点在于系统结构设计和仿真验证
刚去公司的时候BOSS就和我讲,做逻辑的难点不在于RTL级代码的设计,而在于系统
结构设计和仿真验证方面。目前国内对可综合的设计强调的比较多,而对系统结构设计
和仿真验证方面似乎还没有什么资料,这或许也从一个侧面反映了国内目前的设计水平
还比较低下吧。
以前在学校的时候,总是觉得将RTL级代码做好就行了,仿真验证只是形式而已,所
以对HDL的行为描述方面的语法不屑一顾,对testbench也一直不愿意去学--因为觉得画
波形图方便;对于系统结构设计更是一点都不懂了。
到了公司接触了些东西才发现完全不是这样。
其实在国外,花在仿真验证上的时间和人力大概是花在RTL级代码上的两倍,现在仿
真验证才是百万门级芯片设计的关键路径。仿真验证的难点主要在于怎么建模才能完全
和准确地去验证设计的正确性(主要是提高代码覆盖),在这过程中,验证速度也是很
重要的。
验证说白了也就是怎么产生足够覆盖率的激励源,然后怎么去检测错误。我个人认
为,在仿真验证中,最基本就是要做到验证的自动化。这也是为什么我们要写testbenc
h的原因。在我现在的一个设计中,每次跑仿真都要一个小时左右(这其实算小设计)。
由于画波形图无法做到验证自动化,如果用通过画波形图来仿真的话,一是画波形会画
死(特别是对于算法复杂的、输入呈统计分布的设计),二是看波形图要看死,三是检
错率几乎为零。
那么怎么做到自动化呢?我个人的水平还很有限,只能简单地谈下BFM(bus funct
ion model,总线功能模型)。
以做一个MAC的core为例(背板是PCI总线),那么我们需要一个MAC_BFM和PCI_BFM
及PCI_BM(PCI behavior model)。MAC_BFM的主要功能是产生以太网帧(激励源),随
机的长度和帧头,内容也是随机的,在发送的同时也将其复制一份到PCI_BM中;PCI_BFM
的功能则是仿PCI总线的行为,比如被测收到了一个正确帧后会向PCI总线发送一个
请求,PCI_BFM则会去响应它,并将数据收进来;PCI_BM的主要功能是将MAC_BFM发送出
来的东西与PCI_BFM接收到的东西做比较,由于它具有了MAC_BFM的发送信息和PCI_BFM的
接收信息,只要设计合理,它总是可以自动地、完全地去测试被测是否工作正常,
从而实现自动检测。
华为在仿真验证方面估计在国内来说是做的比较好的,他们已建立起了比较好的验
证平台,大部分与通信有关的BFM都做好了,听我朋友说,现在他们只需要将被测放
在测试平台中,并配置好参数,就可以自动地检测被测功能的正确与否。
在功能仿真做完后,由于我们做在是FPGA的设计,在设计时已经基本保证RTL级代码
在综合结果和功能仿真结果的一致性,只要综合布局布线后的静态时序报告没有违反时
序约束的警告,就可以下到板子上去调试了。事实上,在华为中兴,他们做FPGA的设计
时也是不做时序仿真的,因为做时序仿真很花时间,且效果也不见得比看静态时序分析
报告好。
当然了,如果是ASICASIC的设计话,它们的仿真验证的工作量要大一些,在涉及到多时
钟域的设计时,一般还是做后仿的。不过在做后仿之前,也一般会先用形式验证工具和
通过静态时序分序报告去查看有没有违反设计要求的地方,这样做了之后,后仿的工作
量可以小很多。
在HDL语言HDL语言方面,国内语言很多人都在争论VHDLVHDL和verilogverilog哪个好,其实我个人认为
这并没有多大的意义,外面的大公司基本上都是用verilog在做RTL级的代码,所以还是
建议大家尽量学verilog。在仿真方面,由于VHDL在行为级建模方面弱于verilog,用VH
DL做仿真模型的很少,当然也不是说verilog就好,其实verilog在复杂的行为级建模方
面的能力也是有限的,比如目前它还不支持数组。在一些复杂的算法设计中,需要高级
语言做抽象才能描述出行为级模型。在国外,仿真建模很多都是用System C和E语言,用
verilog的都算是很落后的了,国内华为的验证平台好像是用System C写。
在系统结构设计方面,由于我做的设计还不够大,还谈不上什么经验,只是觉得必
须要具备一些计算机系统结构的知识才行。划分的首要依据是功能,之后是选择合适的
总线结构、存储结构和处理器架构,通过系统结构划分要使各部分功能模块清晰,易于
实现。这一部分我想过段时间有一点体会了再和大家分享,就先不误导大家了。
点击查看原文
发表评论 阅读全文(2) | 回复(0)
发表于 2010/4/18 16:20:21
浅淡逻辑设计的学习 学习逻辑设计首先要有项目挂靠,如果你觉得未来一段时间你都不可能有的话,接下来的内容你就没有必要再看了,花的时间再多也只能学到皮毛--很多细节的问题光写代码是发现不到的。而且要真正入门,最好要多做几个项目(这三年大大小小的项目我做有七八个),总线型的和数字信号处理型的最好都要接触一些,因为这两个方向的逻辑设计差异比较大:前者主要是控制型的,会涉及到状态机等控制逻辑;后者主要是计算型的,难点主要在对符号、浮点数转定点数、位宽等方面的处理上。第二要有好的师父。这里说的好的师父并不是指画原理图画了几十年的老师傅,而是指曾在专业IC公司做过一段时间的人,好的专业IC公司可以接触国内外最新的设计思想,在他们的帮助下,起点就可以比其他人高不少,更重要的是你可以学习逻辑设计思想性的东西!如果你的师傅经常跟你说画原理图的好处,你还是重新找过师父算了--用原理图设计是一种很落后的方式,即使他们可能会说可以系统级设计(专业的IC设计公司系统级设计绝对是由方案保证的,而不会靠原理图这鬼东西)更为清淅。第三要看一些好的资料。RTL级的书中《硬件描述语言》、先锋写的那几本书都还可以,还有不得不提的是cliff的一些上有)Writting Testbenches》,提高可以看下snug(Synopsys的用户论坛,里面的文章基本上反映了业界的领先水平)的paper;系统级的可以看看《片上系统-可重用性设计方法学》。第四要自己多总结,多动脑筋。逻辑设计的东西其实本质上的东西并不多:把RTL级的常用的D触发器、计数器、移位寄存器、状态机、多路选择器等基本的电路标准化、固定化;先做方案再写代码;设计时序;知道约束原理及怎么加约束;划分模块时知道怎么做到时序收敛;做验证的时候熟悉相应语言的行为级描述(这个肯定比RTL级好学多了)然后就是理解testbench的结构化设计。把这些东西的本质都搞清楚了做个合格的逻辑工程师应该是绰绰有余了,呵呵。在接下来的部分我主要就第四点随便说点自己的经验,说的不好还请大家批评指正。 入门前
刚才开始接触逻辑设计很多人会觉得很简单:因为verilog的语法不多,半天就可以把书看完了。但是很快许多人就发现这个想法是错误的,他们经常埋怨综合器怎么和自己的想法差别这么大:它竟然连用for循环写的一个计数器都不认识!相信上一段的经历大部分人都曾有,原因是做逻辑设计的思维和做软件的很不相同,我们需要从电路的角度去考虑问题。在这个过程中首先要明白的是软件设计和逻辑设计的不同,并理解什么是硬件意识。软件代码的执行是一个顺序的过程,编绎以后的机器码放在存储器里,等着CPU一条一条的取指并执行;因此软件设计中经常会带有顺序处理的思维。而逻辑设计则不同,我们设计的是数字电路,它是由很多很多的与非门及D触发器构成的,上电之后所有与非门和D触发器都同时工作,不会因为A触发器的代码描述在B触发器之前A触发器就是先工作,事实上,RTL级代码的代码先后顺序在综合成网表文件后这种顺序就消失了,取代的是基本逻辑电路之间的互联关系描述;因此逻辑设计需要的是一种并发的思维,我们也需要用并发的思维去考虑电路的设计。当然,我们设计的电路功能一般都有先后顺序的关系,如果这种顺序不能通过代码的先后顺序来实现,那么要怎么完成这一功能呢?在逻辑设计中,我们所说的先后顺序都是基于时间轴来实现:它的承载体就是时序逻辑,也就是那些触发器。硬件意识的东西网上谈论的已经很多,这里就不再多说了。其次就是要熟悉基本电路的设计。基本的电路不是很多,也就是D触发器、计数器、移位寄存器、状态机、多路选择器、译码器等几种,所有复杂的电路都可由这些基本的电路构成。高手水平高的体现并不是他能写出一些很奇特的电路,相反,水平高是体现在他们总能将复杂的电路用这些很朴素的基本电路去描述。甚至,你会发现他们的代码基本上是由if...else、case这些语句构成的,朴素的让你觉得奇怪。我认为,初学者在入门的时候,对于基本电路的设计应该固定化、标准化,每种电路该用什么样的代码描述,应该要固定、统一,尽量少一些花哨的东西。说来这里我举个例子。以前有几个朋友因为仿真有问题请我帮忙找问题。他们的代码写的很乱,出现了很多种稀奇古怪的电路,一看头都大了,只好建议他们按照标准的电路重新写下代码。结果过了半天,他们就和我说问题不见了。所以,高手们喜欢用简单的代码是有道理的,电路的标准化和规范化可以减少许多稀奇古怪的问题,问题少了他们也就能在别人加班的时候回家多睡回觉,呵呵。总之,简单的、朴素的就是最好的。最后是代码的规范化。代码规范主要是代码书写、命名等规范。比如不能用TAB键空格、低电平有效信号命名时加_n(如rst_n等)、每行只能写一行代码等。这些东西网上也很多,这里只是强烈建议大家要严格遵守,像华为等公司如果代码不规范的话肯定是要打回去重写的。 入门
结合一两个小项目把上面所说的事情都做好后,差不多就可以进入入门的阶段了(要求稍微严格了一点点,呵呵)。入门阶段要学的有:设计时序;理解约束的原理及如何加约束。先谈谈设计时序。设计时序是进行逻辑设计的基本要求:时序是设计出来的,不是仿出来的,更不是凑出来的。很多人在做逻辑设计时喜欢一上来就狂写代码,写到一半后发现信号间的时序出问题了,只好推倒重来;好不容易反复了几次之后,通过仿真软件看了下,差不多要对了,于是再凑一下时序,竟然对了!但这个做法除了设计周期长外,代码的质量也难以保证,往往存在很多冗余的逻辑,甚至有一些隐藏着较深的bug。为什么会出现上面的问题呢?因为我们设计的是数字逻辑,而信号之间的逻辑关系往往是比较复杂的,在内部信号很多的情况下,仅凭拍下脑袋就写代码肯定是不能理清楚它们之前的复杂的关系,所以出错在所难免。正确的做法是我们要先对整个设计有一些规划--时时刻刻都要有设计时序的思想。设计时序最重要的是做好方案,这里说的方案绝不是只是摆几个框图在那里。我们在做设计的时候需要做总体设计方案、逻辑详细设计方案。这两种方案包括了很多东西,逻辑总体方案主要是一级模块的划分及接口时序的定义,而逻辑详细方案就是代码的文字及图形描述!对于入门者来说,接触的比较多的是逻辑详细设计方案。在这一级别的方案中,我们是要求的是至少要做到模块内部所有关键信号的时序都要先设计好,这里讲的设计时序主要就是画波形图,在一个操作周期内每个信号在每一个时钟周期该是什么样子就画成什么样子。附图(时序图)是我曾设计的一个模块的主要信号时序:aes_cnt信号控制着w_fifo_rden、aes_ready等信号,是该模块的关键信号,通过将它们之间的时序关系通过时序图反应出来,写代码时就可以做到胸有成竹,减少出现逻辑混乱的情况。听起来似乎很简单,但是执行起来却不容易,因为画波形图是一件很烦锁的事(有一次一个模块因为操作比较多我画了8张时序图)。但是请相信我,如果不这样做,因为时序关系没有处理好引起设计多次迭代所花的时间远多于画波形图的时间。时序设计好之后,模块内部各个信号之间的关系就理得差不多了,之后就是将它翻译成代码了,这个过程以体力劳动为主,我就不多说了。补充一下,画波形图推荐用TimingDesigner这个软件,如果有更好的,请告诉我,我也不喜欢。另一个就是约束。这里的约束是针对综合软件和布局布线软件而言的。为什么会有约束这个东西出现呢?主要原因是EDA软件比较笨,难以明白我们的心思,如果我们不把更详细的信息告诉它的话它就干不好活,比如需要将输出寄存器放的与输出管脚近一点,如果不加约束,EDA软件可能布通之后就不管了,导致Tco狂大,一点也不善解人意。所以我们需要约束这个东西,告诉EDA软件要怎么干活,工程验收的标准又是什么。在加约束之前,我们首先要定义一些术语好告诉EDA软件我们想干什么,这些术语便是Fmax、Tsu、Tco等等这些东西。这些东西的含义这里就不多说了,网上的讨论已经很多了。有了术语,还要有一种通信方式与EDA软件通信,脚本语言充当了这一角色。不过现在像quartus这类软件做的比较智能化了,提供了图形化界面,但是这背后支撑的还是些脚本语言,大家可以用UltraEdit打加*.qsf文件去看看我们加的约束用脚本语言是怎么写的。
在加了约束之后,EDA工具就可以更好地按照我们的意愿去干活了,比较我们加了Fmax的约束,它就会尽可能地将关键路径放的靠近一些,以提高电路工作频率。当然,这是有代价的,寻找路径是需要时间的,要求越苛刻,时间花的越多,因此加约束的原则的适用就行。如果约束加的过高,就相当于让EDA工具去做一件不可能完成的事,找更短的路径的时候说不定找着找着就掉下悬崖了,效果反而更差。虽然有约束这个好东西,不过提醒一下,在项目之前千万对它抱有太多的幻想,把希望寄托在别人的身上并不是每一次都很可靠的,出了问题还是要麻烦自己,加约束只能做一些锦上添花的事情。所以,我们在做方案的时候就需要对关键路径进行预估,要通过设计而不是约束解决这些问题。
点击查看原文
发表评论 阅读全文(2) | 回复(0)
发表于 2010/4/18 16:20:21
ASIC与FPGA的区别(转) ASIC:application specific integrated circuit专用集成电路,它是面向专门用途的电路。它可以分为全定制,定制,半定制,可编程ASIC。
FPGA:field programmble gate array一种可编程的ASIC,现在已重ASIC的概念中分化出来。
各自的特点为:
ASIC特性
?嵌入式设计
?产量大
?可以不涉及布局布线工作
?ASIC可以支持高速和高度复杂的门级设计
?需要与ASIC厂商密切合作
FPGA特性:
?FPGA主要用作样片试制
?若用于市场需求比较少量的设计,一般不超过一千片
?FPGA等于简单ASIC
?减少库存与设计错误的危险性
?资金投入少
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/18 16:20:21
同步复位和异步复位的比较 一、特点:
同步复位:顾名思义,同步复位就是指复位信号只有在时钟上升沿到来时,才能有效。否则,无法完成对系统的复位工作。用描述如下:
always @ (posedge clk) begin
if (!Rst_n)
...
end
异步复位:它是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。用Verilog描述如下:
always @ (posedge clk or negedge Rst_n) begin
if (!Rst_n)
...
end
二、各自的优缺点:
1、总的来说,同步复位的优点大概有3条:
a、有利于仿真器的仿真。
b、可以使所设计的系统成为100%的同步时序电路,这便大大有利于时序分析,而且综合出来的fmax一般较高。
c、因为他只有在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的毛刺。他的缺点也有不少,主要有以下几条:
a、复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑,诸如:clk skew,组合逻辑路径延时,复位延时等因素。
b、由于大多数的逻辑器件的目标库内的DFF都只有异步复位端口,所以,倘若采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样就会耗费较多的逻辑资源。
2、对于异步复位来说,他的优点也有三条,都是相对应的
a、大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源。
b、设计相对简单。
c、异步复位信号识别方便,而且可以很方便的使用的全局复位端口GSR。
缺点:
a、在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
b、复位信号容易受到毛刺的影响。
三、总结:
所以说,一般都推荐使用异步复位,同步释放的方式,而且复位信号低电平有效。这样就可以两全其美了。
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/18 16:20:21
Quartus警告分析 1.Found clock-sensitive change during active clock edge at time
<time> on register "<name>"
原因:vector source file中时钟敏感信号(如:数据,允许端,清零,同步加
载等)在时钟的边缘同时变化。而时钟敏感信号是不能在时钟边沿变化的。其后
果为导致结果不正确。
措施:编辑vector source file
2.Verilog HDL assignment warning at <location>: truncated
with size <number> to match size of target (<number>
原因:在HDL设计中对目标的位数进行了设定,如:reg[4:0] a;而默认为32位,
将位数裁定到合适的大小
措施:如果结果正确,无须加以修正,如果不想看到这个警告,可以改变设定的位数
3.All reachable assignments to data_out(10) assign '0', register
removed by optimization
原因:经过综合器优化后,输出端口已经不起作用了
4.Following 9 pins have nothing, GND, or VCC driving datain port --
changes to this connectivity may change fitting results
原因:第9脚,空或接地或接上了电源
措施:有时候定义了输出端口,但输出端直接赋‘0’,便会被接地,赋‘1’接电源。
如果你的设计中这些端口就是这样用的,那便可以不理会这些warning
5.Found pins ing as undefined clocks and/or memory enables
原因:是你作为时钟的PIN没有约束信息。可以对相应的PIN做一下设定就行了。
主要是指你的某些管脚在电路当中起到了时钟管脚的作用,比如flip-flop的clk
管脚,而此管脚没有时钟约束,因此QuartusII把“clk”作为未定义的时钟。
措施:如果clk不是时钟,可以加“not clock”的约束;如果是,可以在clock
setting当中加入;在某些对时钟要求不很高的情况下,可以忽略此警告或在这
里修改:Assignments>Timing analysis settings...>Individual
clocks...>...
6.Timing characteristics of device EPM570T144C5 are preliminary
原因:因为MAXII 是比較新的元件在 QuartusII 中的時序并不是正式版的,要
等 Service Pack
措施:只影响 Quartus 的 Waveform
7.Warning: Clock latency analysis for PLL offsets is supported for the
current device family, but is not enabled
措施:将setting中的timing Requirements&Option-->More Timing
Setting-->setting-->Enable Clock Latency中的on改成OFF
8.Found clock high time violation at 14.8 ns on register
"|counter|lpm_counter:count1_rtl_0|dffs[11]"
原因:违反了steup/hold时间,应该是后仿真,看看波形设置是否和时钟沿符
合steup/hold时间
措施:在中间加个寄存器可能可以解决问题
9.warning: circuit may not operate.detected 46 non-operational
paths clocked by clock clk44 with clock skew larger than data delay
原因:时钟抖动大于数据延时,当时钟很快,而if等类的层次过多就会出现这种问
题,但这个问题多是在器件的最高频率中才会出现
措施:setting-->timing Requirements&Options-->Default required
fmax 改小一些,如改到50MHZ
10.Design contains <number> input pin(s) that do not drive logic
原因:输入引脚没有驱动逻辑(驱动其他引脚),所有的输入引脚需要有输入逻辑
措施:如果这种情况是故意的,无须理会,如果非故意,输入逻辑驱动.
11.Warning:Found clock high time violation at 8.9ns on node
'TEST3.CLK'
原因:FF中输入的PLS的保持时间过短
措施:在FF中设置较高的时钟频率
12.Warning: Found 10 node(s) in clock paths which may be acting as
ripple and/or gated clocks -- node(s) analyzed as buffer(s) resulting in
clock skew
原因:如果你用的 CPLD 只有一组全局时钟时,用全局时钟分频产生的另一个时
钟在布线中当作信号处理,不能保证低的时钟歪斜(SKEW)。会造成在这个时钟
上工作的时序电路不可靠,甚至每次布线产生的问题都不一样。
措施:如果用有两组以上全局时钟的 FPGA 芯片,可以把第二个全局时钟作为另
一个时钟用,可以解决这个问题。
13.Critical Warning: Timing requirements were not met. See Report
window for details.
原因:时序要求未满足,
措施:双击Compilation Report-->Time Analyzer-->红色部分(如clock
setup:'clk'等)-->左键单击list path,查看fmax的SLACK REPORT再根据
提示解决,有可能是程序的算法问题
14.Can't achieve minimum setup and hold requirement <text> along
<number> path(s). See Report window for details.
原因:时序分析发现一定数量的路径违背了最小的建立和保持时间,与时钟歪斜
有关,一般是由于多时钟引起的
措施:利用Compilation Report-->Time Analyzer-->红色部分(如clock
hold:'clk'等),在slack中观察是hold time为负值还是setup time 为负值,
然后在:Assignment-->Assignment Editor-->To中增加时钟名(from
node finder),Assignment Name中增加
和多时钟有关的Multicycle 和Multicycle Hold选项,如hold time为负,可
使Multicycle hold的值>multicycle,如设为2和1。
15: Can't analyze file -- file E://quartusii/*/*.v is missing
原因:试图编译一个不存在的文件,该文件可能被改名或者删除了
措施:不管他,没什么影响
16.Warning: Can't find signal in vector source file for input pin
|whole|clk10m
原因:因为你的波形仿真文件( vector source file )中并没有把所有的输入
信号(input pin)加进去,对于每一个输入都需要有激励源的
17.Error: Can't name logic scfifo0 of instance "inst" --
has same name as current design file
原因:模块的名字和project的名字重名了
措施:把两个名字之一改一下,一般改模块的名字
18.Warning: Using design file lpm_fifo0.v, which is not specified as a
design file for the current project, but contains definitions for 1 design
units and 1 entities in project Info: Found entity 1: lpm_fifo0
原因:模块不是在本项目生成的,而是直接copy了别的项目的原理图和源程序
而生成的,而不是用QUARTUS将文件添加进本项目
措施:无须理会,不影响使用
19.Timing characteristics of device <name> are preliminary
原因:目前版本的QuartusII只对该器件提供初步的时序特征分析
措施:如果坚持用目前的器件,无须理会该警告。关于进一步的时序特征分析会
在后续版本的Quartus得到完善。
20.Timing Analysis does not support the analysis of latches as
synchronous elements for the currently selected device family
原因:用analyze_latches_as_synchronous_elements setting可以让
Quaruts II来分析同步锁存,但目前的器件不支持这个特性
措施:无须理会。时序分析可能将锁存器分析成回路。但并不一定分析正确。其
后果可能会导致显示提醒用户:改变设计来消除锁 存器
21.Warning:Found xx output pins without output pin load capacitance
assignment(网友:gucheng82提供)
原因:没有给输出管教指定负载电容
措施:该功能用于估算TCO和功耗,可以不理会,也可以在Assignment Editor
中为相应的输出管脚指定负载电容,以消除警告
22.Warning: Found 6 node(s) in clock paths which may be acting as
ripple and/or gated clocks -- node(s) analyzed as buffer(s) resulting in
clock skew
原因:使用了行波时钟或门控时钟,把触发器的输出当时钟用就会报行波时钟,
将组合逻辑的输出当时钟用就会报门控时钟
措施:不要把触发器的输出当时钟,不要将组合逻辑的输出当时钟,如果本身如
此设计,则无须理会该警告
23.Warning (10268): Verilog HDL information at lcd7106.v(63):
Always Construct contains both blocking and non-blocking
assignments
原因: 一个always模块中同时有阻塞和非阻塞的赋值
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/18 16:20:21
NIOS II中用到的C_C++函数 IO操作函数
函数原型:IORD(BASE, REGNUM)
输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量
函数说明:从基地址为BASE的设备中读取寄存器中偏移量为REGNUM的单元里面的值。寄存器的值在地址总线的范围之内。
返回值: -
函数原型:IOWR(BASE, REGNUM, DATA)
输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量,DATA为要写入的数据
函数说明:往偏移量为REGNUM寄存器中写入数据。寄存器的值在地址总线的范围之内。
返回值: -
函数原型:IORD_32DIRECT(BASE, OFFSET)
输入参数:BASE为寄存器的基地址,OFFSET为寄存器的的偏移量
函数说明:从地址位置为BASE+OFFSET的寄存器中直接读取32Bit的数据
返回值: -
函数原型:IORD_16DIRECT(BASE, OFFSET)
输入参数:BASE为寄存器的基地址,OFFSET为寄存器的的偏移量
函数说明:从地址位置为BASE+OFFSET的寄存器中直接读取16Bit的数据
返回值: -
函数原型:IORD_8DIRECT(BASE, OFFSET)
输入参数:BASE为寄存器的基地址,OFFSET为寄存器的的偏移量
函数说明:从地址位置为BASE+OFFSET的寄存器中直接读取8Bit的数据
返回值: -
函数原型:IOWR_32DIRECT(BASE, OFFSET, DATA)
输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量,DATA为要写入的数据
函数说明:往地址位置为BASE+OFFSET的寄存器中直接写入32Bit的数据
返回值: -
函数原型:IOWR_16DIRECT(BASE, OFFSET, DATA)
输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量,DATA为要写入的数据
函数说明:往地址位置为BASE+OFFSET的寄存器中直接写入16Bit的数据
返回值: -
函数原型:IOWR_8DIRECT(BASE, OFFSET, DATA)
输入参数:BASE为寄存器的基地址,REGNUM为寄存器的偏移量,DATA为要写入的数据
函数说明:往地址位置为BASE+OFFSET的寄存器中直接写入8Bit的数据
返回值: -
Dma:
函数原型:int alt_dma_rxchan_close (alt_dma_rxchan rxchan)
输入参数:rxchan为接收信道
函数说明:函数 alt_dma_rxchan_close ()通知系统:应用程序已经完成DMA
接收信道rxchan,目前执行是成功的
返回值: 成功返回为0,反之为-1
函数原型:alt_dma_rxchan_depth(alt_dma_rxchan dma)
输入参数:dma
函数说明:函数alt_dma_rxchan_depth ()返回传送到特别DMA的最大数量(深度)的接收请求
返回值: DMA的最大数量
函数原型:int alt_dma_rxchan_ioctl (alt_dma_rxchan dma, int req, void* arg)
输入参数:dma直接存储器名, req为请求操作的列举, arg由请求决定
函数说明:通过DMA接收信道执行设备的具体I/O操作
返回值: 成功返回请求具体值,反之返回为负数
请求类型
请求类型 请求类型说明
ALT_DMA_SET_MODE_8 传输以8Bit为单位的数据,arg值忽略
ALT_DMA_SET_MODE_16 传输以16Bit为单位的数据,arg值忽略
ALT_DMA_SET_MODE_32 传输以32Bit为单位的数据,arg值忽略
ALT_DMA_SET_MODE_64 传输以64Bit为单位的数据,arg值忽略
ALT_DMA_SET_MODE_128 传输以128Bit为单位的数据,arg值忽略
ALT_DMA_TX_ONLY_ON (1) 软件控制下只能发送
ALT_DMA_TX_ONLY_OFF (1) 自定义模式,软件控制下可以接收,发送
ALT_DMA_RX_ONLY_ON (1) 软件控制下只能接收
ALT_DMA_RX_ONLY_OFF (1) 自定义模式,软件控制下可以接收,发送
函数原型:alt_dma_rxchan alt_dma_rxchan_open (const char* name)
输入参数:name为常数字符指针,如/dev/dma_0
函数说明:为DMA接收信道获得一个alt_dma_rxchan描述符
返回值: 成功返回非0,反之返回为0
函数原型:int alt_dma_rxchan_prepare (alt_dma_rxchan dma, void* data,
alt_u32 length, alt_rxchan_done * done, void* handle)
输入参数:dma使用的信道;data接收数据位置的指针;length最大的接收数据长度;done一旦数据被接收,调用返回函数;handle,非透明值传到done
函数说明:发送一个接收请求到DMA接收信道,
返回值: 成功返回0,反之返回为负数
函数原型:int alt_dma_rxchan_reg (alt_dma_rxchan_dev * dev)
输入参数:dev接收信道设备名
函数说明:给系统寄存DMA接收信道
返回值: 成功返回0,反之返回为负数
函数原型:int alt_dma_txchan_close (alt_dma_txchan txchan)
输入参数:txchan发送信道名
函数说明:通知系统:应用程序已经完成DMA发送信道txchan
返回值: 成功返回0,反之返回为负数
函数原型:int alt_dma_txchan_ioctl (alt_dma_txchan dma, int req, void* arg)
输入参数:dma直接存储器名;req为请求操作的列举;arg请求的额外参数,由请求决定
函数说明:通过DMA发送信道执行设备的具体I/O操作
返回值: 成功返回请求具体值,反之返回为负数
函数原型:alt_dma_txchan alt_dma_txchan_open (const char* name)
输入参数:name为常数字符指针,如/dev/dma_0
函数说明:为DMA发送信道获得一个alt_dma_rxchan描述符
返回值: 成功返回非0,反之返回为0
函数原型:int alt_dma_txchan_reg (alt_dma_txchan_dev* dev)
输入参数:dev接收信道设备名
函数说明:给系统寄存DMA发送信道
返回值: 成功返回0,反之返回为负数
函数原型:int alt_dma_txchan_send (alt_dma_txchan dma, const void* from,
alt_u32 length, alt_txchan_done* done, void* handle)
输入参数:dma使用的信道;data接收数据位置的指针;length最大的接收数据长度;done一旦数据被接收,调用返回函数;handle,非透明值传到done
函数说明:发送一个发送请求到DMA发送信道,
返回值: 发送成功返回0,反之返回为负数
函数原型:nt alt_dma_txchan_space (alt_dma_txchan dma)
输入参数:dma 直接存储器名
函数说明:返回被传送到具体DMA发送信道的发送请求数目
返回值: 返回发送请求数目
Flash
函数原型:int alt_erase_flash_block(alt_flash_fd* fd, int offset, int length)
输入参数:fd为具体的flash设备;offset擦除的flash模块的偏移量;length擦除的flash模块的长度
函数说明:擦除单独的一个flash模块
返回值: 发送成功返回0,反之返回为负数
函数原型:void alt_flash_close_dev(alt_flash_fd * fd)
输入参数:fd为具体的flash设备
函数说明:关闭flash设备
返回值: -
函数原型:alt_flash_fd * alt_flash_open_dev(const char* name)
输入参数:
函数说明:打开flash设备。一旦打开,函数alt_write_flash()用来写入,函数alt_read_flash()用来读取数据,或者使用函数alt_get_flash_info(), alt_erase_flash_block(), alt_write_flash_block(),控制单个模块
返回值: 失败返回0,成功其他值
函数原型:int alt_get_flash_info(alt_flash_fd* fd, flash_region ** info,
int* number_of_regions)
输入参数:fd flash设备;info指向flash_region结构体的指针;number_of_regions
函数说明:得到擦除flash区域的细节
返回值: 发送成功返回0,反之返回为负数
函数原型:int alt_read_flash(alt_flash_fd* fd, int offset, void* dest_addr, int length)
输入参数:dest_addr目标地址指针
函数说明:从flash偏移量为offset字节开始读取数据,写入到目标地址dest_addr中
返回值: 成功返回0,反之为非0
函数原型:int alt_write_flash(alt_flash_fd* fd, int offset, const void* src_addr,
int length)
输入参数:src_addr源地址;fd,flash设备;offset 偏移量;length字节长度
函数说明:写数据到flsah中,要写的数据在源地址src_addr中
返回值: 成功返回0,反之为非0
函数原型:int alt_write_flash_block(alt_flash_fd* fd, int block_offset, int data_offset,
const void *data, int length)
输入参数:fd;data_offset起始写数据的偏移量;length为要写数据的长度
函数说明:写入到一个已擦除的flash模块
返回值: 成功返回0,反之为非0
Irq
函数原型:alt_irq_context alt_irq_disable_all (void)
输入参数:void
函数说明:禁止所有中断
返回值: 传递的值作为随后的函数调用的输入参数
函数原型:void alt_irq_enable_all (alt_irq_context context)
输入参数:先前调用函数alt_irq_disable_all (void)的返回值,
函数说明:启动所有中断
返回值: -
函数原型:int alt_irq_enabled (void)
输入参数:void
函数说明:启动中断
返回值: 禁止中断返回0,反之为非0
函数原型:int alt_irq_register (alt_u32 id, void* context, void (*isr)(void*, alt_u32))
输入参数:id,32位无符号数,中断使能;context和id是isr的两个输入参数;中断激活时调用isr
函数说明:寄存一个isr
返回值: 成功返回0,反之为非0
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/18 16:04:46
点击查看原文
发表评论 阅读全文(2) | 回复(0)
发表于 2010/4/18 16:04:46
学好NiosII必须具备的条件- - 经过1年多的学习和实践,我总结了下面几条要学好niosII所需要具备的条件:
1.良好的英文阅读能力:因为所有的nios的权威资料都是来自与下面的altera的官方网站
2.C语言的基础以及部分汇编基础
3.最基本的单片机的硬件基础
4.一个nios的参考开发板,最好是来自于altera公司
5.一定的QuartusII的基础
6.一定的调试能力: NiosII IDE是基于eclipse架构的,该IDE具备非常强大的调试能力
比如:
breakpoint
watchpoint
register view
memory view
variable view
trace==
7.添加一点,要想学好Nios,最好能带着项目学习
给大家一个强烈的建议:
要想学好Nios,调试能力是非常重要的
通过调试,你可以逐渐的了解nios的整个软件架构,比如它是如何处理中断的,又是如何处理bootloader的,等等
还有NiosII IDE里面有非常多的属性设置,基本上每个设置都有它的作用,等你了解了所有设置的功能,也就差不多算半个高手了^_^
还有很重要的一点就是如何寻找帮助:
1. Altera的官方网站有一个mysupport,在那里可以提交service request, 不过只支持英文
2. Altera的官方网站有Find Answer的功能,输入问题的关键字,可能就可以直接得到答案
3. Nios的官方论坛, ,这是个英文网站,里面很多斑竹都是Nios的开发者
4. 咱们这个EDA论坛也不赖
5. Altera的FAE
6. 其实我用到的最多的帮助是Altera的nios资料,在里面几乎可以找到所有的答案^_^
下面补充一下如何查找资料:
1.
在Nios的安装目录下,有个document文件夹C:\altera\kits\nios2_51\documents
该文件夹下有个index.htm文件
如果大家仔细认真的研究一下这个文件,一定可以从中得到非常多的收获,
以后碰上问题的话基本上都可以从这个网页开始自己寻找答案
2.
还有一个很重要的帮助途径
Click NiosII IDE->Help->Help Contents
此时会弹出一个Help的网页,该网页支持搜索功能,你可以在里面输入你所要查找的关键字,就可以得到相关内容.
比如你想知道如何在NiosII IDE里面创建自己的库文件,那么你就可以查找managed library的关键字^_^
差点忘了一个非常重要的学习资源了,就是altera提供的视频教程:
在这个网址有个课程列表,其中很大一部分的视频教程是免费的,内容非常丰富^_^
这里是关于niosII的一些视频demo,对初学者非常有帮助^_^
点击查看原文
发表评论 阅读全文(1) | 回复(0)
发表于 2010/4/18 15:58:59
FPGA开发板各存储器之间的联系 在FPGA开发板上都有几种不同的存储器,比如SDRAM,FLASH,EPCS,还有内部onchip memory,这几种存储器间是如何通信或者构建一个系统
该如何搭配他们呢,不少人都问到这个问题。在这里我做个总结以方便初学者的学习。
首先看看在sopc builder中reset address和nios IDE中System Library中的program memory(.text)、read-only data memory(.rodata)等
这几个地址的关系和作用
根据altera 的文档解释如下:
.text :代码执行区
.rodata:只读数据区,存放静态全局变量
.rwdata:可读写数据区,存放可读写变量和指针变量
.bss:未初始化变量区
.text-the actual executable code
.rodata-where read only data used in the execution of the code
.rwdata-where read/write variables and pointers are stored
heap-where dynamically allocated memory is located
stack-where function call parameters and other temporary data
SOPC builder 在Nios II more "cpu_0" setting 标签中的
reset address决定了flash programmer 的下载存储器(一般是选EPCS controller 或者CFI flash),并且决定了程序从此处开始启动。exception address指定的是异常处理地址。当然,程序在运行前所有的数据都是存放在flash(EPCS或者CFI FLASH)中如果你设计的系统reset address与其它地址的设置不相同,比如reset address 和exceprion address,reset address 和IDE中的program memory(.text)设成不同的存储器,那么系统从reset address启动时都会从flash中把相关数据自动下载到相应的地址或者初始化相应地址。
通过上面的认识,我们就比较清楚了各存储器间可进行哪些搭配了,reset address的选择可选EPCS controllor 或者CFI flash;program memory(.text)可选择onchip memory,SDRAM,CFI flash等。如果reset address为EPCS则在使用flash progrrammer时程序是下载到EPCS芯片中。如果reset address选择CFI flash,则flash progrrammer时程序是下载到CFI flash芯片中。
需要注意的是这里有个特殊情况。例如在开发板上经常有这么一个简单的系统,CPU+onchip memory+LED_PIO,reset address选择onchip memory;感觉整个系统都没有用到flash。而且onchip memory在系统断电后数据就会消失,那么程序代码是存在哪,系统是如何从onchip memory启动听呢?先来看看onchip memory模块的描述信息:在onchip_memory.v中有这么一段the_altsyncram.init_file = "onchip_memory.hex",很明显onchip memory的初始数据来自"onchip_memory.hex",而"onchip_memory.hex"是在Nios IDE的System Library中存储器有选择onchip_memory(至少有一项是选择onchip_memory,如果都不选,就不会生成)时,在build结束的时候生成的。于是当我们把System Library中存储器的选择都选择onchip_memory时,在IDE中build结束后所有的程序代码都生成在"onchip_memory.hex"中,再在QII中全编译一次时,系统通过onchip_memory.v调用"onchip_memory.hex"从而把所有的程序代码以及配制信息都生成在POF和SOF文件中,使用QII的programmer直接下载到EPCS芯片或者FPGA芯片内程序都会立即执行。因为这里的特殊性就有很多网友询问了,reset address 选择onchip memory,而IDE中把代码区都选择SDRAM调试的时候程序正常运行,再在QII全编译后下载POF文件就运行不了呢?问题就是出在这了,在这里可以总结出一点,要让程序在onchip memory之外的存储器中运行,那么reset address就必然选EPCS 或者CFI flash,并且要通过flash programmer把程序下载到flash中。
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/18 15:58:59
关于建立时间、保持时间的讨论 时钟周期为T,触发器D1的时钟沿到来到触发器Q变化的时间Tco(CLK--Q)最大为T1max,最小为T1min,逻辑组合电路的延迟时间最大为T2max,最小为T2min,问触发器D2的建立时间和保持时间。
maxbird: D2的保持时间就是时钟沿到来之后,D2的数据输入端要保持数据不变的时间,这个时间是由D1和D2之间的组合逻辑时延决定的。例如:假设D1和D2之间的组合逻辑时延为2ns,时钟周期为10ns,这意味着在时钟沿来到后,D1输出的新数据要过2ns才会到达D2的数据输入端,那么在这2ns内,D2的数据输入端保持的还是上一次的旧数据,其值不会立即更新,假设D2的最小保持时间为3ns,这意味时钟沿到来后,D2的数据输入端的值在3ns内不能有变化,回到问题的关键,由于D1在时钟沿到来后的输出结果,经过2ns的组合逻辑延时便到达了D2的输入端,而D2要求在时钟沿到来后的3ns内其输入端的值不能改变,这样D2的保持时间就得不到满足,所以D2的保持时间必须小于等于2ns。 至于说T2min为0时的情况,其实T2min是永远不能为0的,即使是一根导线其时延也是不可能为0的,这就是为什么移位寄存器的两个触发器之间连的只是一根导线,导线后端触发器的保持时间却还是可以满足的原因,其实移位寄存器中触发器的保持时间可以看成是小于等于其间导线的时延。
建立时间:触发器在时钟沿来到前,其数据输入端的数据必须保持不变的时间;保持时间:触发器在时钟沿来到后,其数据输入端的数据必须保持不变的时间。如下图:
因为触发器内部数据的形成是需要一定的时间的,如果不满足建立和保持时间,触发器将进入亚稳态,进入亚稳态后触发器的输出将不稳定,在0和1之间变化,这时需要经过一个恢复时间,其输出才能稳定,但稳定后的值并不一定是你的输入值。这就是为什么要用两级触发器来同步异步输入信号。这样做可以防止由于异步输入信号对于本级时钟可能不满足建立保持时间而使本级触发器产生的亚稳态传播到后面逻辑中,导致亚稳态的传播。两级触发器可防止亚稳态传播的原理:假设第一级触发器的输入不满足其建立保持时间,它在第一个脉冲沿到来后输出的数据就为亚稳态,那么在下一个脉冲沿到来之前,其输出的亚稳态数据在一段恢复时间后必须稳定下来,而且稳定的数据必须满足第二级触发器的建立时间,如果都满足了,在下一个脉冲沿到来时,第二级触发器将不会出现亚稳态,因为其输入端的数据满足其建立保持时间。同步器有效的条件:第一级触发器进入亚稳态后的恢复时间 + 第二级触发器的建立时间 < = 时钟周期。 (编者注:maxbird在该部分详细说明了建立时间和保持时间的概念,以及如果不满足二者可能导致的亚稳态的传播。注意这里说的建立时间和保持时间都是针对时钟而言的,在进行时序约束时所指的就是这种,而很多网友以前学习的建立时间保持时间的概念是针对信号而言的,所指的对象不同,分析出来的结论完全相反,一定注意不要混淆。)
lh1688: 不考虑CLOCK SKEW情况下。D2的建立时间要求:Tco1+T1(logic delay)+Tsetup2 < Tc(CLOCK 周期) 。那么 Tsetup2 < Tc(CLOCK 周期) -(Tco1+T1)。这个应该比较容易理解。相对的保持时间实际就是 路径的总延时 (Tco1+T1)。 保持时间 Thold2 < (Tco1+T1)。
点击查看原文
发表评论 阅读全文(2) | 回复(0)
发表于 2010/4/17 17:16:54
QuartusII警告信息大解析(zz) ********************************************************************
在II下进行编译和仿真的时候,会出现一堆warning,有的可以忽略,有的却需要注意,虽然按F1可以了解关于该警告的帮助,但有时候帮助解释的仍然不清楚,大家群策群力,把自己知道和了解的一些关于警告的问题都说出来讨论一下,免得后来的人走弯路.
下面是我收集整理的一些,有些是自己的经验,有些是网友的,希望能给大家一点帮助,如有不对的地方,请指正,如果觉得好,请版主给点威望吧,谢谢
1.Found clock-sensitive change during activeclockedge at time <time> on register "<name>"
原因:vector sourcefile中时钟敏感信号(如:数据,允许端,清零,同步加载等)在时钟的边缘同时变化。而时钟敏感信号是
不能在时钟边沿变化的。其后果为导致结果不正确。
措施:编辑vector source file
2. assignment warning at <location>: truncated value with size <number> to match size of target (<number>
原因:在HDL设计中对目标的位数进行了设定,如:reg[4:0] a;而默认为32位,将位数裁定到合适的大小
措施:如果结果正确,无须加以修正,如果不想看到这个警告,可以改变设定的位数
3.All reachable assignments to data_out(10) assign '0', register removed by optimization
原因:经过综合器优化后,输出端口已经不起作用了
4.Following 9 pins have nothing, GND, or VCC driving datain port -- changes to this connectivity may change fitting results
原因:第9脚,空或接地或接上了电源
措施:有时候定义了输出端口,但输出端直接赋‘0’,便会被接地,赋‘1’接电源。如果你的设计中这些端口就是这样用的,那便可以不理会这些warning
5.Found pins functioning as undefined clocks and/or memory enables
原因:是你作为时钟的PIN没有约束信息。可以对相应的PIN做一下设定就行了。主要是指你的某些管脚在电路当中起到了时钟管脚的
作用,比如flip-flop的clk管脚,而此管脚没有时钟约束,因此QuartusII把“clk”作为未定义的时钟。
措施:如果clk不是时钟,可以加“not clock”的约束;如果是,可以在clock setting当中加入;在某些对时钟要求不很高的情况下,可以忽略此警告或在这里修改:Assignments>Timing analysis settings...>Individualclocks...>...
注意在Applies to node中只用选择时钟引脚一项即可,required fmax一般比所要求频率高5%即可,无须太紧或太松。
6.Timing characteristics of device EPM570T144C5 are preliminary
原因:因为MAXII 是比較新的元件在 QuartusII 中的時序並不是正式版的,要等 Service Pack
措施:只影响 Quartus 的 Waveform.
7.Warning: Clock latency analysis for PLL offsets is supported for the current device family, but is not enabled
措施:将setting中的timing Requirements&Option-->More Timing Setting-->setting-->Enable Clock Latency中的on改成OFF
8.Found clock high time violation at 14.8 ns on register "|counter|lpm_counter:count1_rtl_0|dffs[11]"
原因:违反了steup/hold时间,应该是后仿真,看看波形设置是否和时钟沿符合steup/hold时间
措施:在中间加个寄存器可能可以解决问题
9.warning: circuit may not operate.detected 46 non-operational paths clocked by clock clk44 with clockskewlarger than data delay
原因:时钟抖动大于数据延时,当时钟很快,而if等类的层次过多就会出现这种问题,但这个问题多是在器件的最高频率中才会出现
措施:setting-->timing Requirements&Options-->Default required fmax 改小一些,如改到50MHZ
10.Designcontains <number> input pin(s) that do not drive logic
原因:输入引脚没有驱动逻辑(驱动其他引脚),所有的输入引脚需要有输入逻辑
措施:如果这种情况是故意的,无须理会,如果非故意,输入逻辑驱动.
12.Warning: Found 10 node(s) in clock paths which may be acting as ripple and/or gated clocks -- node(s) analyzed as buffer(s) resulting in clock skew
原因:如果你用的 只有一组全局时钟时,用全局时钟分频产生的另一个时钟在布线中当作信号处理,不能保证低的时钟歪斜(SKEW)。会造成在这个时钟上工作的时序电路不可靠,甚至每次布线产生的问题都不一样。
措施:如果用有两组以上全局时钟的 [url=][url=][/url][/url]芯片,可以把第二个全局时钟作为另一个时钟用,可以解决这个问题。
13.Critical Warning: Timing requirements were not met. See Report window for details.
原因:时序要求未满足,
措施:双击Compilation Report-->Time Analyzer-->红色部分(如clock setup:'clk'等)-->左键单击list path,查看fmax的SLACK REPORT再根据提示解决,有可能是程序的算法问题或fmax设置问题
14.Warning: Can't find signal in vector source file for input pin |whole|clk10m
原因:这个时因为你的波形仿真文件( vector source file )中并没有把所有的输入信号(input pin)加进去, 对于每一个输入都需要有激励源的
15.Can't achieve minimum setup and hold requirement <text> along <number> path(s). See Report window for details.
原因:时序分析发现一定数量的路径违背了最小的建立和保持时间,与时钟歪斜有关,一般是由于多时钟引起的
措施:利用Compilation Report-->Time Analyzer-->红色部分(如clock hold:'clk'等),在slack中观察是hold time为负值还是setup time 为负值,然后在:Assignment-->Assignment Editor-->To中增加时钟名(fromnode finder),Assignment Name中增加和多时钟有关的Multicycle 和Multicycle Hold选项,如hold time为负,可使Multicycle hold的值>multicycle,如设为2和1。
16: Can't analyze file -- file E://quartusii/*/*.v is missing
原因:试图编译一个不存在的文件,该文件可能被改名或者删除了
措施:不管他,没什么影响
17.Warning: Can't find signal in vector source file for input pin |whole|clk10m
原因:因为你的波形仿真文件( vector source file )中并没有把所有的输入信号(input pin)加进去, 对于每一个输入都需要有激励源的
18.Error: Can't name logic function scfifo0 of instance "inst" -- function has same name as current design file
原因:模块的名字和project的名字重名了
措施:把两个名字之一改一下,一般改模块的名字
19.Warning: Using design file lpm_fifo0.v, which is not specified as a design file for the current project, but contains definitions for 1 design units and 1 entities in project Info: Found entity 1: lpm_fifo0
原因:模块不是在本项目生成的,而是直接copy了别的项目的原理图和源程序而生成的,而不是用QUARTUS将文件添加进本项目
措施:无须理会,不影响使用
20.Timing characteristics of device <name> are preliminary
原因:目前版本的QuartusII只对该器件提供初步的时序特征分析
措施:如果坚持用目前的器件,无须理会该警告。关于进一步的时序特征分析会在后续版本的Quartus得到完善。
21.Timing Analysis does not support the analysis of latches as synchronous elements for the currently selected device family
原因:用analyze_latches_as_synchronous_elements setting可以让Quaruts II来分析同步锁存,但目前的器件不支持这个特性
措施:无须理会。时序分析可能将锁存器分析成回路。但并不一定分析正确。其后果可能会导致显示提醒用户:改变设计来消除锁存器,但实际其实无关紧要
22.Warning:Found xx output pins without output pin load capacitance assignment
原因:没有给输出管教指定负载电容
解决方法:该功能用于估算TCO和功耗,可以不理会,也可以在Assignment Editor中为相应的输出管脚指定负载电容,以消除警告
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/17 16:52:58
一些关于微电子方面的笔试题(有答案) 专用集成电路,它是面向专门用途的电路,专门为一个用户设计和制造的。根据一个用户的特定要求,能以低研制成本,短、交货周期供货的全定制,半定制集成电路。与门阵列等其它ASIC(Application Specific IC)相比,它们又具有设计开发周期短、设计制造成本低、开发工具先进、标准产品无需测试、质量稳定以及可实时在线检验等优点
建立时间是指触发器的时钟信号上升沿到来以前,数据稳定不变的时间。输入信号应提前时钟上升沿(如上升沿有效)T时间到达芯片,这个T就是建立时间如不满足setup time,这个数据就不能被这一时钟打入触发器,只有在下一个时钟上升沿,数据才能被打入触发器。保持时间是指触发器的时钟信号上升沿到来以后,数据稳定不变的时间。如果hold time不够,数据同样不能被打入触发器。 建立时间是指在时钟边沿前,数据信号需要保持不变的时间。保持时间是指时钟跳变边沿后数据信号需要保持不变的时间。如果不满足建立和保持时间的话,那么DFF将不能正确地采样到数据,将会出现metastability(亚稳态)的情况。如果数据信号在时钟沿触发前后持续的时间均超过建立和保持时间,那么超过量就分别被称为建立时间裕量和保持时间裕量。
在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决方法:一是添加布尔式的消去项,二是在芯片外部加电容。 列举几种集成电路典型工艺。工艺上常提到0.25,0.18指的是什么?(仕兰微面试题目)制造工艺:我们经常说的0.18微米、0.13微米制程,就是指制造工艺了。制造工艺直接关系到cpu的电气性能。而0.18微米、0.13微米这个尺度就是指的是cpu核心中线路的宽度。线宽越小,cpu的功耗和发热量就越低,并可以工作在更高的频率上了。所以以前0.18微米的cpu最高的频率比较低,用0.13微米制造工艺的cpu会比0.18微米的制造工艺的发热量低都是这个道理了。 集成电路前段设计流程,写出相关的工具。(扬智电子笔试)
1.)代码输入(
语言输入工具:SUMMIT VISUALHDL
MENTOR RENIOR
图形输入: composer(cadence);
viewlogic (viewdraw)
2.)电路仿真(circuit simulation)
将vhd代码进行先前逻辑仿真,验证功能描述是否正确
数字电路仿真工具:
Verolog: CADENCE Verolig-XL
SYNOPSYS VCS
MENTOR Modle-sim
VHDL : CADENCE NC-vhdl
SYNOPSYS VSS
MENTOR Modle-sim
模拟电路仿真工具:
***ANTI HSpice pspice,spectre micro microwave: eesoft : hp 3.)逻辑综合(逻辑综合工具可以将设计思想vhd代码转化成对应一定工艺手段的门级电路;将初级仿真中所没有考虑的门沿(gates delay)反标到生成的门级网表中,返回电路仿真阶段进行再仿真。最终仿真结果生成的网表称为物理网表。 7、解释setup和hold time violation,画图说明,并说明解决办法。(威盛VIA 2003.11.06上海笔试试题) Setup/hold time是测试芯片对输入信号和时钟信号之间的时间要求。建立时间是指触发器的时钟信号上升沿到来以前,数据稳定不变的时间。输入信号应提前时钟上升沿(如上升沿有效)T时间到达芯片,这个T就是建立时间-Setup time.如不满足setup time,这个数据就不能被这一时钟打入触发器,只有在下一个时钟上升沿,数据才能被打入触发器。保持时间是指触发器的时钟信号上升沿到来以后,数据稳定不变的时间。如果hold time不够,数据同样不能被打入触发器。 建立时间(Setup Time)和保持时间(Hold time)。建立时间是指在时钟边沿前,数据信号需要保持不变的时间。保持时间是指时钟跳变边沿后数据信号需要保持不变的时间。如果不满足建立和保持时间的话,那么DFF将不能正确地采样到数据,将会出现metastability的情况。如果数据信号在时钟沿触发前后持续的时间均超过建立和保持时间,那么超过量就分别被称为建立时间裕量和保持时间裕量。 在组合逻辑中,由于门的输入信号通路中经过了不同的延时,导致到达该门的时间不一致叫竞争。产生毛刺叫冒险。如果布尔式中有相反的信号则可能产生竞争和冒险现象。解决方法:一是添加布尔式的消去项,二是在芯片外部加电容。 亚稳态是指触发器无法在某个规定时间段内达到一个可确认的状态。当一个触发器进入亚稳态时,既无法预测该单元的输出电平,也无法预测何时输出才能稳定在某个正确的电平上。在这个稳定期间,触发器输出一些中间级电平,或者可能处于振荡状态,并且这种无用的输出电平可以沿信号通道上的各个触发器级联式传播下去。 同步复位在时钟沿采复位信号,完成复位动作。异步复位不管时钟,只要复位信号满足条件,就完成复位动作。异步复位对复位信号要求比较高,不能有毛刺,如果其与时钟关系不确定,也可能出现亚稳态。 不同的时钟域之间信号通信时需要进行同步处理,这样可以防止新时钟域中第一级触发器的亚稳态信号对下级逻辑造成影响,其中对于单个控制信号可以用两级同步器,如电平、边沿检测和脉冲,对 跨时域的信号要经过同步器同步,防止亚稳态传播。例如:时钟域1中的一个信号,要送到时钟域2,那么在这个信号送到时钟域2之前,要先经过时钟域2的同步器同步后,才能进入时钟域2。这个同步器就是两级d触发器,其时钟为时钟域2的时钟。这样做是怕时钟域1中的这个信号,可能不满足时钟域2中触发器的建立保持时间,而产生亚稳态,因为它们之间没有必然关系,是异步的。这样做只能防止亚稳态传播,但不能保证采进来的数据的正确性。所以通常只同步很少位数的信号。比如控制信号,或地址。当同步的是地址时,一般该地址应采用格雷码,因为格雷码每次只变一位,相当于每次只有一个同步器在起作用,这样可以降低出错概率,象异步FIFO的设计中,比较读写地址的大小时,就是用这种方法。 如果两个时钟域之间传送大量的数据,可以用异步FIFO来解决问题。 10、给了reg的setup,hold时间,求中间组合逻辑的delay范围。(飞利浦-大唐笔试)
Delay < period - setup 11、时钟周期为T,触发器D1的寄存器到输出时间最大为T1max,最小为T1min。组合逻辑电路最大延迟为T2max,最小为T2min。问,触发器D2的建立时间T3和保持时间应满足什么条件。(华为)
12、说说静态、动态时序模拟的优缺点。(威盛VIA 2003.11.06上海笔试试题)
静态时序分析是采用穷尽分析方法来提取出整个电路存在的所有时序路径,计算信号在这些路径上的传播延时,检查信号的建立和保持时间是否满足时序要求,通过对最大路径延时和最小路径延时的分析,找出违背时序约束的错误。它不需要输入向量就能穷尽所有的路径,且运行速度很快、占用内存较少,不仅可以对芯片设计进行全面的时序功能检查,而且还可利用时序分析的结果来优化设计,因此静态时序分析已经越来越多地被用到数字集成的验证中。 动态时序模拟就是通常的仿真,因为不可能产生完备的测试向量,覆盖门级网表中的每一条路径。因此在动态时序分析中,无法暴露一些路径上可能存在的时序问题; 同步电路:存储电路中所有触发器的时钟输入端都接同一个时钟脉冲源,因而所有触发器的状态的变化都与所加的时钟脉冲信号同步。 异步电路:电路没有统一的时钟,有些触发器的时钟输入端与时钟脉冲源相连,这有这些触发器的状态变化与时钟脉冲同步,而其他的触发器的状态变化不与时钟脉冲同步。 什么是NMOS、PMOS、CMOS?什么是增强型、耗尽型?什么是PNP、NPN?他们有什么差
别?
MOS场效应管即金属-氧化物-半导体型场效应管,英文缩写为MOSFET(Metal-Oxide-Semiconductor Field-Effect-Transistor),属于绝缘栅型。其主要特点是在金属栅极与沟道之间有一层二氧化硅绝缘层,因此具有很高的输入电阻(最高可达1015Ω)。它也分N沟道管和P沟道管,符号如图1所示。通常是将衬底(基板)与源极S接在一起。根据导电方式的不同,MOSFET又分增强型、耗尽型。所谓增强型是指:当VGS=0时管子是呈截止状态,加上正确的VGS后,多数载流子被吸引到栅极,从而“增强”了该区域的载流子,形成导电沟道。耗尽型则是指,当VGS=0时即形成沟道,加上正确的VGS时,能使多数载流子流出沟道,因而“耗尽”了载流子,使管子转向截止。 PNP与NPN的区别在表面上是以PN结的方向来定义的,实际上是以三极管的结构材料来区分的。PNP是两边的棒料是镓,中间的是硅。镓是第三主族的元素,其核外为三个电子,硅是第四主族的元素,其核外有四个电子,这样在两个PN的方向上的顺序是P-N-N的关系;相反NPN是两边的材料是硅,中间的是镓,形成的PN结顺序为N-P-N的关系。
顺便说明:P的意思是在PN结上缺少电子,以空穴为主导电的材料,也叫P型材料;N的意思是在PN结上有多余的电子,以电子为主导电的材料,也叫N型材料。 根据不同分频系数设置适当的计数器周期,每个计数值对应输入时钟信号fi的一个周期,让q0只在fi的上升沿及适当的计数范围内产生高电平,最后将q0和q1进行逻辑或操作,进而得到所需的分频信号fo。q1的作用是在奇数分频中补足下降沿处半个时钟周期,使其等占空比,以及在半整数分频中,在时钟下降沿处产生分频信号的上升沿,以实现半整数分频。
下面介绍如何确定计数器周期以及q0、q1产生高电平输出时各自的计数范围。为叙述方便,现规定如下标记:分频系数为divide(MAX downto 0),其中MAX是分频数对应二进制数的最高位,对于半整数分频,最低位即第0位为小数位;q 0_count和q1_count分别为q0和q1产生高电平的计数范围,并记divide(MAX downto 1)为a,divide(MAX downto 2)为b,divide(MAX downto 0)-1为c。
计数器周期都为0到c。等占空比的偶数分频很容易实现,在此不加叙述。对奇数分频,只需当q0_count<a时q0输出高电平,当q1_count=a-1时q1输出一个周期的高电平,其他情况下q0和q1都为低电平,然后把q0和q1逻辑或,所得的输出fo就是所需的基数分频时钟信号。
计数器周期为0到c。如果整数部分是偶数,只需当q0_count<b时q0输出高电平,当b≤q1_count<a+b时q1输出高电平,其他情况下,q0和q1都为低电平;如果整数部分是奇数,只需当q0_coun≤b时q0输出高电平,当b≤q1_count≤a+b输出高电平,其他情况下q0和q1都为低电平,然后把q0和q1逻辑或所得输出f0即所需的半整数分频时钟信号。
1、latch由电平触发,非同步控制。在使能信号有效时latch相当于通路,在使能信号无效时latch保持输出状态。DFF由时钟沿触发,同步控制。
2、latch容易产生毛刺(glitch),DFF则不易产生毛刺。
3、如果使用门电路来搭建latch和DFF,则latch消耗的门资源比DFF要少,这是latch比DFF优越的地方。所以,在ASIC中使用latch的集成度比DFF高,但在FPGA中正好相反,因为FPGA中没有标准的latch单元,但有DFF单元,一个LATCH需要多个LE才能实现。
一般的设计规则是:在绝大多数设计中避免产生latch。它会让您设计的时序完蛋,并且它的隐蔽性很强,非老手不能查出。latch最大的危害在于不能过滤毛刺。这对于下一级电路是极其危险的。所以,只要能用D触发器的地方,就不用latch。
有些地方没有时钟,也只能用latch了。比如现在用一个clk接到latch的使能端(假设是高电平使能),这样需要的setup时间,就是数据在时钟的下降沿之前需要的时间,但是如果是一个DFF,那么setup时间就是在时钟的上升沿需要的时间。这就说明如果数据晚于控制信号的情况下,只能用latch,这种情况就是,前面所提到的latch timing borrow。基本上相当于借了一个高电平时间。也就是说,latch借的时间也是有限的。
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/17 16:27:13
LVDS技术原理和设计简 作者:南京中兴通讯研究所(210002) 张 健 南京邮电学院(210003) 吴晓冰 来源:《电子技术应用》
LVDS技术原理和设计简介
--------------------------------------------------------------------------------
摘 要: 介绍了LVDS(低电压差分信号)技术的原理和应用,并讨论了在单板和系统设计中应用LVDS时的布线技巧。
1 LVDS介绍
LVDS(Low Voltage Differential Signaling)是一种低摆幅的差分信号技术,它使得信号能在差分PCB线对或平衡电缆上以几百Mbps的速率传输,其低压幅和低电流驱动输出实现了低噪声和低功耗。
几十年来,5V供电的使用简化了不同技术和厂商逻辑电路之间的接口。然而,随着集成电路的发展和对更高数据速率的要求,低压供电成为急需。降低供电电压不仅减少了高密度集成电路的功率消耗,而且减少了芯片内部的散热,有助于提高集成度。
减少供电电压和逻辑电压摆幅的一个极好例子是低压差分信号(LVDS)。LVDS物理接口使用1.2V偏置提供400mV摆幅的信号(使用差分信号的原因是噪声以共模的方式在一对差分线上耦合出现,并在接收器中相减从而可消除噪声)。LVDS驱动和接收器不依赖于特定的供电电压,因此它很容易迁移到低压供电的系统中去,而性能不变。作为比较,ECL和PECL技术依赖于供电电压,ECL要求负的供电电压,PECL参考正的供电电压总线上电压值(Vcc)而定。而GLVDS是一种发展中的标准尚未确定的新技术,使用500mV的供电电压可提供250mV 的信号摆幅。不同低压逻辑信号的差分电压摆幅示于图1。
LVDS在两个标准中定义。IEEE P1596.3(1996年3月通过),主要面向SCI(Scalable Coherent Interface),定义了LVDS的电特性,还定义了SCI协议中包交换时的编码;ANSI/EIA/EIA-644(1995年11月通过),主要定义了LVDS的电特性,并建议了655Mbps的最大速率和1.823Gbps的无失真媒质上的理论极限速率。在两个标准中都指定了与物理媒质无关的特性,这意味着只要媒质在指定的噪声边缘和歪斜容忍范围内发送信号到接收器,接口都能正常工作。 LVDS具有许多优点:①终端适配容易;②功耗低;③具有fail-safe特性确保可靠性;④低成本;⑤高速传送。这些特性使得LVDS在计算机、通信设备、消费电子等方面得到了广泛应用。
图2给出了典型的LVDS接口,这是一种单工方式,必要时也可使用半双工、多点配置方式,但一般在噪声较小、距离较短的情况下才适用。每个点到点连接的差分对由一个驱动器、互连器和接收器组成。驱动器和接收器主要完成TTL信号和LVDS信号之间的转换。互连器包含电缆、PCB上差分导线对以及匹配电阻。LVDS驱动器由一个驱动差分线对的电流源组成通常电流为3.5mA),LVDS接收器具有很高的输入阻抗,因此驱动器输出的电流大部分都流过100Ω的匹配电阻,并在接收器的输入端产生大约350mA 的电压。当驱动器翻转时,它改变流经电阻的电流方向,因此产生有效的逻辑″1″和逻辑″0″状态。低摆幅驱动信号实现了高速操作并减小了功率消耗,差分信号提供了适当噪声边缘和功率消耗大幅减少的低压摆幅。功率的大幅降低允许在单个集成电路上集成多个接口驱动器和接收器。这提高了PCB板的效能,减少了成本。
不管使用的LVDS传输媒质是PCB线对还是电缆,都必须采取措施防止信号在媒质终端发生反射,同时减少电磁干扰。LVDS要求使用一个与媒质相匹配的终端电阻(100±20Ω),该电阻终止了环流信号,应该将它尽可能靠近接收器输入端放置。LVDS驱动器能以超过155.5Mbps的速度驱动双绞线对,距离超过10m。对速度的实际限制是:①送到驱动器的TTL数据的速度;②媒质的带宽性能。通常在驱动器侧使用复用器、在接收器侧使用解复用器来实现多个TTL信道和一个LVDS信道的复用转换,以提高信号速率,降低功耗。并减少传输媒质和接口数,降低设备复杂性。
LVDS接收器可以承受至少±1V的驱动器与接收器之间的地的电压变化。由于LVDS驱动器典型的偏置电压为+1.2V,地的电压变化、驱动器偏置电压以及轻度耦合到的噪声之和,在接收器的输入端相对于接收器的地是共模电压。这个共模范围是:+0.2V~+2.2V。建议接收器的输入电压范围为:0V~+2.4V。
2 LVDS系统的设计
LVDS系统的设计要求设计者应具备超高速单板设计的经验并了解差分信号的理论。设计高速差分板并不很困难,下面将简要介绍一下各注意点。
2.1 PCB板
(A)至少使用4层PCB板(从顶层到底层):LVDS信号层、地层、电源层、TTL信号层;
(B)使TTL信号和LVDS信号相互隔离,否则TTL可能会耦合到LVDS线上,最好将TTL和LVDS信号放在由电源/地层隔离的不同层上;
(C)使LVDS驱动器和接收器尽可能地靠近连接器的LVDS端;
(D)使用分布式的多个电容来旁路LVDS设备,表面贴电容靠近电源/地层管脚放置;
(E)电源层和地层应使用粗线,不要使用50Ω布线规则;
(F)保持PCB地线层返回路径宽而短;
(G)应该使用利用地层返回铜线(gu9ound return wire)的电缆连接两个系统的地层;
(H) 使用多过孔(至少两个)连接到电源层(线)和地层(线),表面贴电容可以直接焊接到过孔焊盘以减少线头。
2.2 板上导线
(A) 微波传输线(microstrip)和带状线(stripline)都有较好性能;
(B) 微波传输线的优点:一般有更高的差分阻抗、不需要额外的过孔;
(C) 带状线在信号间提供了更好的屏蔽。
2.3 差分线
(A)使用与传输媒质的差分阻抗和终端电阻相匹配的受控阻抗线,并且使差分线对离开集成芯片后立刻尽可能地相互靠近(距离小于10mm),这样能减少反射并能确保耦合到的噪声为共模噪声;
(B)使差分线对的长度相互匹配以减少信号扭曲,防止引起信号间的相位差而导致电磁辐射;
(C)不要仅仅依赖自动布线功能,而应仔细修改以实现差分阻抗匹配并实现差分线的隔离;
(D)尽量减少过孔和其它会引起线路不连续性的因素;
(E)避免将导致阻值不连续性的90°走线,使用圆弧或45°折线来代替;
(F)在差分线对内,两条线之间的距离应尽可能短,以保持接收器的共模抑制能力。在印制板上,两条差分线之间的距离应尽可能保持一致,以避免差分阻抗的不连续性。
2.4 终端
(A)使用终端电阻实现对差分传输线的最大匹配,阻值一般在90~130Ω之间,系统也需要此终端电阻来产生正常工作的差分电压;
(B)最好使用精度1~2%的表面贴电阻跨接在差分线上,必要时也可使用两个阻值各为50Ω的电阻,并在中间通过一个电容接地,以滤去共模噪声。
2.5 未使用的管脚
所有未使用的LVDS接收器输入管脚悬空,所有未使用的LVDS和TTL输出管脚悬空,将未使用的TTL发送/驱动器输入和控制/使能管脚接电源或地。
2.6 媒质(电缆和连接器)选择
(A)使用受控阻抗媒质,差分阻抗约为100Ω,不会引入较大的阻抗不连续性;
(B)仅就减少噪声和提高信号质量而言,平衡电缆(如双绞线对)通常比非平衡电缆好;
(C)电缆长度小于0.5m时,大部分电缆都能有效工作,距离在0.5m~10m之间时,CAT 3(Categiory 3)双绞线对电缆效果好、便宜并且容易买到,距离大于10m并且要求高速率时,建议使用CAT 5双绞线对。
2.7 在噪声环境中提高可靠性设计
LVDS 接收器在内部提供了可靠性线路,用以保护在接收器输入悬空、接收器输入短路以及接收器输入匹配等情况下输出可靠。但是,当驱动器三态或者接收器上的电缆没有连接到驱动器上时,它并没有提供在噪声环境中的可靠性保证。在此情况下,电缆就变成了浮动的天线,如果电缆感应到的噪声超过LVDS内部可靠性线路的容限时,接收器就会开关或振荡。如果此种情况发生,建议使用平衡或屏蔽电缆。另外,也可以外加电阻来提高噪声容限,如图3所示。 图中R1、R3是可选的外接电阻,用来提高噪声容限,R2≈100Ω。
当然,如果使用内嵌在芯片中的LVDS收发器,由于一般都有控制收发器是否工作的机制,因而这种悬置不会影响系统。
3 应用实例
LVDS技术目前在高速系统中应用的非常广泛,本文给出一个简单的例子来看一下具体的连线方式。加拿大PMC公司的DSLAM(数字用户线接入模块)方案中,利用LVDS技术实现点对点的单板互联,系统结构可扩展性非常好,实现了线卡上的高集成度,并且完全能够满足业务分散、控制集中带来的大量业务数据和控制流通信的要求。 图4描述了该系统线卡与线卡之间、线卡与背板之间的连线情形,使用的都是单工方式,所以需要两对线来实现双向通信。图中示出了三种不同连接方式,从上到下分别为:存在对应连接芯片;跨机架时实现终端匹配;同层机框时实现终端匹配。在接收端串接一个变压器可以减小干扰并避免LVDS驱动器和接收器地电位差较大的影响。
点击查看原文
发表评论 阅读全文(0) | 回复(0)
发表于 2010/4/17 9:28:15
FPGA设计流程(转) 1.设计输入
1)设计的行为或结构描述。
2)典型文本输入工具有UltraEdit-32和Editplus.exe.。
3)典型图形化输入工具-Mentor的Renoir。
4)我认为UltraEdit-32最佳。
2.代码调试
1)对设计输入的文件做代码调试,语法检查。
2)典型工具为Debussy。
3.前仿真
1)功能仿真
2)验证验证逻辑模型(没有使用时间延迟)。
3)典型工具有Mentor公司的ModelSim、Synopsys公司的VCS和VSS、Aldec公司的Active、Cadense公司的NC。
4)我认为做功能仿真Synopsys公司的VCS和VSS速度最快,并且调试器最好用,Mentor公司的ModelSim对于读写文件速度最快,波形窗口比较好用。
4.综合
1)把设计翻译成原始的目标工艺
2)最优化
3)合适的面积要求和性能要求
4)典型工具有Mentor公司的LeonardoSpectrum、Synopsys公司的DC、Synplicity公司的Synplify。
5)推荐初学者使用Mentor公司的LeonardoSpectrum,由于它在只作简单约束综合后的速度和面积最优,如果你对综合工具比较了解,可以使用Synplicity公司的
Synplify。
5.布局和布线
1)映射设计到目标工艺里指定位置
2)指定的布线资源应被使用
3)由于PLD市场目前只剩下Altera,Xilinx,Lattice,Actel,QuickLogic,Atmel六家公司,其中前5家为专业PLD公司,并且前3家几乎占有了90%的市场份额,
而我们一般使用Altera,Xilinx公司的PLD居多,所以典型布局和布线的工具为Altera公司的Quartus II和Maxplus II、Xilinx公司的ISE和Foudation。
4)Maxplus II和Foudation分别为Altera公司和Xilinx公司的第一代产品产品,所以布局布线一般使用Quartus II和ISE。
6.后仿真
1)时序仿真
2)验证设计一旦编程或配置将能在目标工艺里工作(使用时间延迟)。
3)所用工具同前仿真所用软件。
7.时序分析
4)一般借助布局布线工具自带的时序分析工具,也可以使用Synopsys公司的 PrimeTime软件和Mentor Graphics公司的Tau timing analysis软件。
8.验证合乎性能规范
1)验证合乎性能规范,如果不满足,回到第一步。
9.版图设计
1)验证版版图设计。
2)在板编程和测试器件。
点击查看原文
发表评论 阅读全文(34) | 回复(1)
发表于 2010/4/16 19:30:46
关于inout口的使用(转) 见许多问这个问题的,总结一下,希望能对大家有点用处,如果有不对的地方,欢迎指出.
芯片外部引脚很多都使用inout类型的,为的是节省管腿。一般信号线用做总线等双向数据传输的时候就要用到
INOUT类型了。就是一个端口同时做输入和输出。 inout在具体实现上一般用三态门来实现。三态门的第三个状态就是高阻'Z'。 当inout端口不输出时,将三态门置高阻。这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tri-state的资料.
1 使用inout类型数据,可以用如下写法:
inout data_inout;
input data_in;
reg data_reg;//data_inout的映象寄存器
reg link_data;
assign data_inout=link_data?data_reg:1’bz;//link_data控制三态门
//对于data_reg,可以通过组合逻辑或者时序逻辑根据data_in对其赋值.通过控制link_data的高低电平,从而设置data_inout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输入端口使用.link_data可以通过相关电路来控制.
2 编写测试模块时,对于inout类型的端口,需要定义成wire类型变量,而其它输入端口都定义成reg类型,这两者是有区别的.
当上面例子中的data_inout用作输入时,需要赋值给data_inout,其余情况可以断开.此时可以用assign语句实现:assign data_inout=link?data_in_t:1’bz;其中的link ,data_in_t是reg类型变量,在测试模块中赋值.
另外,可以设置一个输出端口观察data_inout用作输出的情况:
Wire data_out;
Assign data_out_t=(!link)?data_inout:1’bz;
else,in RTL
inout use in top module(PAD)
dont use inout(tri) in sub module
也就是说,在内部模块最好不要出现inout,如果确实需要,那么用两个port实现,到顶层的时候再用三态实现。理由是:在非顶层模块用双向口的话,该双向口必然有它的上层跟它相连。既然是双向口,则上层至少有一个输入口和一个输出口联到该双向口上,则发生两个内部输出单元连接到一起的情况出现,这样在综合时往往会出错。
举例说明
输入口din定义:input[7:0]din;当双向端口
dinout作为输出口时,我们从din端口输入数据到
模块中,让数据从dinout口出来。
输出口dout定义:output[7:0]dout;当双向
端口dinout作为输入口时,我们让数据从dinout口
输入,从输出口dout输出。
双向端口dinout定义:inout[7:0]dinout;
三态门选通信号z:inputz;
当z=1时,把三态门置为高阻态,这时dinout
作为输入口用;当z=0时,开通三态门,这时dinout
作为输出口用。
三态门控制语句为:
assigndinout=(!z)?din_reg:8'bz;
总的完整程序如下:
moduledinout(din,z,clk,dout,dinout);
input [7:0]din;
input z;
input clk;
output [7:0]dout;
inout [7:0]dinout;
reg [7:0]dout;
reg [7:0]din_reg;
assigndinout=(!z)?din_reg:8'bz;
|