Verilog的可综合描述风格学习目标:学习组合逻辑和时序逻辑的可综合的描述风格及技术,包括:•不支持的Verilog结构•过程块•寄存器•敏感列表•持续赋值•综合指导•条件结构•阻塞及非阻塞赋值•锁存器/MUX推断•函数function•任务task•复位•有限状态机FSM•宏库及设计复用描述风格简介如果逻辑输出在任何时候都直接由当前输入组合决定,则为组合逻辑。如果逻辑暗示存储则为时序逻辑。如果输出在任何给定时刻不能由输入的状态决定,则暗示存储。通常综合输出不会只是一个纯组合或纯时序逻辑。一定要清楚所写的源代码会产生什么类型输出,并能够反过来确定为什么所用的综合工具产生这个输出,这是非常重要的。不支持的Verilog结构综合工具通常不支持下列Verilog结构:initial循环:repeatforeverwhile非结构化的for语句数据类型:eventrealtimeUDPfork…join块wait过程持续赋值:assigndeassignforcerelease操作符:===!==过程块•任意边沿–在所有输入信号的任意边沿进入的过程块产生组合逻辑。这种过程块称为组合块。always@(aorb)//与门y=a&b;单单单沿–在一个控制信号的单一边沿上进入的过程块产生同步逻辑。这种过程块称为同步块。always@(posedgeclk)//Dflip-flopq<=d;–同步块也可以对异步复位信号的变化产生敏感always@(posedgeclkornegedgerst_)if(!rst_)q<=0;elseq<=d;过程块中的寄存器类型若同步块中使用一个reg,则:•如果在一个时钟周期赋值并在另一个周期被采样,则只能以硬件寄存器实现。•如果reg还是一个基本输出,它会出现在综合网表中,但不一定是一个硬件寄存器。•若两者都不是,该信号可能被优化掉。若组合块中使用一个reg,则:•如果reg值随块的任何一个输入的变化而改变,则在综合时不会产生硬件寄存器。•如果reg值并不总是随块的输入变化而改变,则综合时会产生一个锁存器。同步寄存器举例在这个例子中,rega只作暂存,因此会被优化掉。moduleex1reg(d,clk,q);inputd,clk;outputq;regq,rega;always@(posedgeclk)beginrega=0;if(d)rega=1;q=rega;endendmodule在这个例子中,rega产生一个寄存器,不会被优化掉。moduleex2reg(d,clk,q);inputd,clk;outputq;regq,rega;always@(posedgeclk)beginrega=0;if(d)rega=1;endalways@(posedgeclk)q=rega;endmodule组合逻辑中的寄存器类型举例在这个例子中,y和rega总是赋新值,因此产生一个纯组合逻辑。moduleex3reg(y,a,b,c);inputa,b,c;outputy;regy,rega;always@(aorborc)beginif(a&b)rega=c;elserega=0;y=rega;endendmodule在这个例子中,rega不总是产生新值,因此会产生一个锁存器,y是锁存器的输出moduleex4reg(y,a,b,c);inputa,b,c;outputy;regy,rega;always@(aorborc)beginif(a&b)rega=c;y=rega;endendmodule在下面的例子,rega是暂存变量,并被优化掉敏感列表敏感表不完全:modulesens(a,q,b,sl);inputa,b,sl;outputq;regq;always@(sl)beginif(!sl)q=a;elseq=b;endendmodule完全的敏感列表modulesensc(q,a,b,sl);inputa,b,sl;outputq;regq;always@(sloraorb)beginif(!sl)q=a;elseq=b;endendmodule在下面的例子,a,b,sl是块的输入•sl用作条件•a、b用在过程赋值语句的右边将块的所有输入都列入敏感表是很好的描述习惯。不同的综合工具对不完全敏感表的处理有所不同。有的将不完全敏感表当作非法。其他的则产生一个警告并假设敏感表是完全的。在这种情况下,综合输出和RTL描述的仿真结果可能不一致。敏感列表将块的所有输入都列入敏感表是很好的描述习惯。不同的综合工具对不完全敏感表的处理有所不同。有的将不完全敏感表当作非法。其他的则产生一个警告并假设敏感表是完全的。在这种情况下,综合输出和RTL描述的仿真结果可能不一致。上述两例综合结果(SYNOPSYS)相同,但RTL描述的仿真结果不同。也就是左边的敏感表不完全的例子的RTL描述和综合出的网表的仿真结果不同。modulesens_t;rega,b,sl;sensu1(a,q,b,sl);senscu2(qc,a,b,sl);initialbegin$monitor($time,"%b%b%b%b%b",a,b,sl,q,qc);a=0;b=0;sl=0;#10a=1;#10sl=1;#10sl=0;#10$finish;endendmodule000000101000120101003010011持续赋值moduleo...