NUAA1高级VHDL设计•可靠设计与高速设计NUAA2进度•1.绪论。•2.设计流程。•3.模块化硬件与进程模型。•4.信号传输模型。•5.核心语法与基础电路设计。•6.状态机设计。•8.可编程逻辑器件。•7.可靠设计与高速设计。•9.数字信号处理的fpga实现。•10.数字系统的RTL设计。声明•本部分内容是数字电子系统的芯片级设计中要遇到的特殊问题,虽不是考试重点,但却是实际设计中的关键注意事项。•精选自一部分出版书籍、网络资料以及个人的一些设计经验,仅仅是众多设计原则和设计技巧中的沧海一粟,并且错误在所难免。•艺无止境,讲授本部分的目的仅仅是带领入门,修行仍靠自身。要熟练使用这些技巧,并且有进一步的提高,必须经过大量的项目实践去积累。NUAA4OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段增加设计稳定性和工作速率的方法掺杂在这几部分内容中,不根据本部分的题目做硬性的划分。NUAA5OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA6OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA7VHDL结构体描述风格•行为描述风格可进行系统仿真,少数可用于综合。•RTL描述风格寄存器传输级描述,也能为数据流描述风格。一般可被综合器综合。•结构描述风格多用于顶层的模块连接。NUAA8行为描述风格•这种风格的描述往往以以下语句为主要特征:–使用延时语句,包括惯性延时和传输延时;–在多驱动的处理上采取判决函数;–使用Generic语句对时序参数建模;–使用其它具备行为级特性的语句如waitfor等语句。•这部分属于高级仿真内容,在此不作讲述。NUAA9结构体描述风格•特征语句:–PORTMAP;–GENERICMAP。•不作详细讲述。NUAA10RTL描述风格•面向可综合的设计,处于抽象设计与门级设计之间的层次。•其对应的硬件层次为寄存器云图NUAA11OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA12RTL描述风格注意事项1.“X”状态的传递2.时钟沿描述限制3.关联性强的信号应该放在一个进程中NUAA131.“X”状态的传递(1)•不确定态“X”在前仿真中经常会出现。当然综合以后的时序仿真中一般是不会出现的。•在RTL级的描述中,要做好“X”状态的处理,以使得前仿真和后仿真的结果一致。NUAA141.“X”状态的传递(2)•例子:•if(sel=‘1’)then•y=‘0’;•else•y=‘1`;•endif;•从门级的观点看,该分支隐含的条件为:If(sel=‘0’)。•因此在后仿真时没问题,因为sel一般不会出现‘X’。•但是前仿真时,当sel=‘X’时,会得出y=‘1’的结果,违反了电路原理。NUAA151.“X”状态的传递(3)•例子:•if(sel=‘1’)then•y=‘0’;•elsif(sel=‘0’)then•y=‘1’;•else•y=‘X`;•endif;•加上‘X’状态的处理。NUAA161.“X”状态的传递(4)•实际上,第一种描述方式在设计中也是很经常见的,但是这个时候要尽力避免不确定态的出现:–电路初始化要完善,特别是时序电路中要有可靠的复位描述;–尽量少用组合回环或反馈;–测试矢量要完善。NUAA171.“X”状态的传递(5)•时序电路的复位例子:时钟处理模块(2分频)•Process(clk)•Begin•If(clk’eventandclk=‘1’)then•clk2d=notclk2d;•Endif;•Endprocess;NUAA181.“X”状态的传递(5)•时序电路的复位例子:时钟处理模块(2分频)•Process(clk,reset_n)•Begin•if(reset_n=‘0’)thenclk2d=‘0’;•elsIf(clk’eventandclk=‘1’)then•clk2d=notclk2d;•Endif;•Endprocess;•注:时序电路的复位是强烈推荐使用的,但是在某些情况下,复位电路会稍微降低系统的工作速率。是否取消复位电路,要看具体的目标芯片和系统的速率需求。NUAA191.“X”状态的传递(6)•组合回环的避免•组合电路•这种组合回环,用VHDL的逻辑运算语句来描述,会无法通过综合;用portmap语句来描述可通过综合。•RTL级别描述的组合回环很少使用(并且不推荐使用),一般仅用在一些特殊场合中(比如多时钟切换中的毛刺避免等),但是这在仿真时dout往往会出现不确定态,这是必须要注意的。doutNUAA202.时钟沿描述限制(1)•一个进程中,只能有一个时钟沿判断语句!•Process(clk1,clk2)•Begin•if(clk1’eventandclk1=‘1’)then•…•endif;•if(clk2’eventandclk2=‘1’)then•endif;•Endprocess;NUAA212.时钟沿描述限制(2)•一个进程中,只能有一个时钟沿判断语句!•Process(clk)•Begin•if(clk’eventandclk=‘1’)then•…•endif;•if(clk’eventandclk=‘1’)then•endif;•Endprocess;NUAA222.时钟沿描述限制(3)•所以,不能在一个进程中判断两次或以上的时钟沿,甚至是判断同一个时钟的两个沿也不行。NUAA23OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA24敏感信号的问题(1)1.敏感信号表只对前仿真引擎起作用,对综合器不起作用,而综合后生成的仿真模型是保证不遗漏敏感信号的,因此设计者不小心造成的敏感信号表的遗漏往往会导致前仿真和后仿真的不一致。NUAA25敏感信号的问题(2)2.引起硬件动作的被读信号应该都放在敏感信号表中,纯组合电路描述中的所有被读的信号都必须放在敏感信号表中,这些信号包括:1)组合电路描述中,所有被读取的信号;2)时序电路中的时钟信号,异步控制信号。NUAA26敏感信号的问题(3)•敏感信号表遗漏情况下,前仿真的波形看起来很像锁存,因此这种错误在某些资料中也称为“仿真锁存器”。NUAA27OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA28条件判断语句的注意事项•锁存的避免•无关态的使用•优先级问题NUAA29锁存的避免•冗余锁存器的其他例子,可参考sry5_核心语法与基础电路设计.ppt的条件判断语句部分。这里只做补充。•例子:设计一个状态机,一共有两个状态s0,s1。输入信号为一个比特的din。当din=‘1’时,状态机进行状态翻转;当din=‘0’时,状态保持为当前态。•描述方法1:可以将din当成状态机时钟clk的使能;本方法在此不再讲述。•描述方法2:按照状态机描述的三进程模板进行描述,以下是状态寄存器和次态译码进程。译码输出进程省略。NUAA30•状态寄存器进程:•Process(clk,reset)•Begin•if(reset=‘1’)then•Pst=s0;•elsif(clk’eventandclk=‘1’)then•pst=Nst;•endif;•Endprocess;•次态译码进程•Process(Pst,din)•Begin•casePstis•whens0=•if(din=‘1’)then•Nst=s1;•else•Nst=s0;•endif;•whens1=….•Endprocess;•在din=‘0’时,初学者往往认为状态机不翻转,则可不必再对Nst赋值,因为此时Nst和Pst的值一样,都为s0,再赋值一次显得多余。NUAA32•事实上,这个“多余”的赋值非常致命,少了这一句,电路将出现惊人的复杂化,并且工作不正常。因为次态译码从纯组合电路变成了锁存电路。•思考:上一页中,初学者思路的漏洞在哪里?•解答:在初始时刻,也就是在reset之后,如果din=‘0’,则Nst没有获得明确的值。它只好“保持原来状态”。上述思路的漏洞在于没有考虑到初始时刻的情况,而是假定电路已经发生状态翻转之后再作分析。NUAA33锁存的避免--总结•组合电路描述中,条件判断语句必须指明所有条件分支情况下,被赋值信号的值。•分支不完整,意味着电路需要在某种电平状态下,让被赋值的信号“保持原值”,这只能使用锁存电路实现。NUAA34无关态的使用•代码段1:•Caseselis•when“000”=dout=dina;•when“010”=dout=dinb;•whenothers=dout=‘0’;•Endcase;NUAA35无关态的使用•代码段2:•Caseselis•when“000”=dout=dina;•when“010”=dout=dinb;•whenothers=dout=‘-’;•Endcase;NUAA36•代码段1的综合结果:MUXdoutdinadinbSel(0)Sel(1)Sel(2)NUAA37•代码段2的综合结果:MUXdinadinbdout•Sel(1)NUAA38无关态的使用--总结•对比以上两段代码的综合结果,可以发现,善于使用无关态‘-’来填补分支,可以引导综合工具生成很优化的电路。•无关态‘-’在本质上时起了冗余电路删简的作用。NUAA39优先级问题1.Case语句无优先级,if语句有优先级。2.Multipleifstatement和singleifstatement具有两种不同的优先级顺序。NUAA40Singleif•Process(a)•Begin•if(a(0)=‘1’)thenb=“001”;•elsif(a(1)=‘1’)thenb=“010”;•elsif(a(2)=‘1’)thenb=“100”;•elseb=“000”;•endif;•Endprocess;NUAA41Multipleif•Process(a)•Begin•b=“000”;•if(a(0)=‘1‘)thenb=“001”;endif;•if(a(1)=‘1‘)thenb=“010”;endif;•if(a(2)=‘1‘)thenb=“100”;endif;•Endprocess;NUAA42OUTLINE•正确设计•同步设计•异步设计•高速设计的其他手段•VHDL结构体描述风格•rtl风格注意事项•敏感信号的问题•条件判断语句的注意事项•多驱动与总线复用•毛刺的消除NUAA43多驱动与总线复用•当多个信号源同时去驱动同一个负载,就会形成多驱动。可暂且简单称为输出碰撞。•没有处理好多驱动,不但会造成逻辑混乱,而且容易损坏器件。NUAA44多驱动与总线复用•多驱动处理的要点:–行为级思维硬件思维;–总线复用;–线与;–双向端口中的高阻态;NUAA45多驱动与总线复用•多驱动处理的要点:–行为级思维硬件思维;–总线复用;–线与;–双向端口中的高阻态;软件思维硬件思维的转变•在电路描述时,必须摒弃软件思维方式,一切从硬件的角度去思考代码的描述。•在具体的项目实践中,必须先画好模块的接口时序图,然后画出或者在脑子里形成模块的内部原理框图,最后才是代码实现。•企图一开始就依靠“软件算法”思维进行代码实现,最后才分析时序和电路图,是非常不可取的。