首页计算机计算机工程硬件描述语言和数字系统设计 10 第10章 Verilog的可综合描述风格.pptx

10 第10章 Verilog的可综合描述风格.pptx

页数:78页文件大小:1.11 MB来源: 硬件描述语言和数字系统设计ppt课件

本课件系统梳理可综合描述风格:不支持综合的Verilog结构,过程块电平与边沿触发对应的电路类型,reg被综合成触发器、锁存器或连线的条件,敏感量列表完整性,条件语句与锁存器推断,赋值类型的选择,复位与多驱动问题。

第10章Verilog的可综合描述风格章节封面,标示本章涵盖正确使用过程块来表达组合逻辑和时序逻辑、寄存器reg被综合为D触发器、组合逻辑敏感量列表完整性等内容
第10章学习目标,依次讲述正确使用过程块来表达组合逻辑和时序逻辑、寄存器reg被综合为D触发器、组合逻辑敏感量列表完整性等小节
函数function/任务task的内容页,综合情况10.8组合逻辑反馈环的避免10.9阻塞赋值-非阻塞赋值10.10同步复位,异步复位10.11多
查看本课件的文字版(共 78 页,供检索与复制)

第1页:第10章Verilog的可综合描述风格

硬件描述语言和数字系统设计

第2页:第10章学习目标

学习目标
学习组合逻辑和时序逻辑的可综合的描述风格及技术,包括:10.1正确使用过程块来表达组合逻辑和时序逻辑10.2寄存器reg被综合为D触发器,信号线或者锁存器的不同情况10.3组合逻辑敏感量列表完整性,时序逻辑敏感量列表10.4持续赋值语句综合情况10.5可综合条件语句的注意事项:锁存器的推断,优先级问题,晚到达的信号的处理.10.6非结构化的for循环

第3页:函数function/任务task的

综合情况10.8组合逻辑反馈环的避免10.9阻塞赋值-非阻塞赋值10.10同步复位,异步复位10.11多驱动问题(multiple drive/ multipleconcurrent)10.12优化-尽量资源共享10.13复杂操作符

第4页:正确使用过程块来表达组合逻辑和时序逻辑

不支持的Verilog结构综合工具通常不支持下列Verilog结构:数据类型:event real timeinitial语句循环语句:repeatforeverwhileUDP fork…join块wait过程持续赋值:assign deassignforce release操作符:= = = ! = =

第5页:寄存器reg被综合为D触发器

可综合的时序逻辑与组合逻辑的Verilog行为级描述1.组合逻辑可用连续赋值,过程块来描述:如果被赋值对象是线型(常用wire型),则用连续赋值(assign)对它进行描述;如果被赋值对象是寄存器型(常用reg型),则用always这种过程块值对它进行描述,采用电平触发的方式,其中always敏感量列表应包括:所有阻塞赋值等号右边的信号,和作为condition被条件语句(if或case语句)判断的信号.2.时序逻辑用always这种过程块并结合非阻塞赋值对它进行描述,被赋值对象是寄存器型(常用reg型),采用边沿触发(posedge/negedge)的方式,其中always敏感量列表一般为一个边沿触发的时钟信号,最多再加一个边沿触发的复位信号.

第6页:组合逻辑敏感量列表完整性

时序逻辑与组合逻辑的选择如果逻辑输出在任何时候都直接由当前输入组合决定,则为组合逻辑。如果逻辑暗示存储则为时序逻辑。如果输出信号不是直接由输入的信号决定,则暗示存储。1.一定要清楚所写的源代码会产生什么的类型输出;2.并能够反过来确定为什么所用的综合工具产生这个输出,这是非常重要的。

第7页:持续赋值语句综合情况

过程块

  • 电平触发–在所有相关信号(输入信号或者内部信号)的任意信号变化进入的过程块产生组合逻辑。这种过程块称为组合块。always@(aorb)//与门y=a&b;
  • 边沿触发–在一个控制信号的单一边沿上进入的过程块产生同步逻辑。这种过程块称为同步块。always@(posedgeclk)//Dflip-flopq<=d;–同步块也可以对异步复位信号的变化产生敏感always@(posedgeclkornegedgerst_)if(!rst_)q<=0;elseq<=d;

第8页:持续赋值语句综合情况(续1)

过程块-5分频电路(占空比为50%)的电平描述module divide5error(rst,clk,clk5); input rst,clk; output clk5; reg clk5; reg [2:0] counter; always @(clk or rst)if (!rst) counter <=3'b000; else if(counter==3'b100)counter <=3'b000; else counter <= counter+1; always @(rst or counter)if (!rst) clk5=1'b0; else if(counter==3'b100)clk5=~clk5; endmodule;

第9页:持续赋值语句综合情况(续2)

仿真波形分析
从仿真波形上看,满足5分频要求,但是,综合的电路情况是否同样满足呢?

第10页:持续赋值语句综合情况(续3)

Leonardo工具综合的电路图综合时报告的Warning:1.Warning, input clk is never used.2.Warning,clk5 is not always assigned.Storage may be needed.3.Warning, Designcontains combinatorial loopthrough net counter(0),counter(1), counter(2).

第11页:持续赋值语句综合情况(续4)

过程块-电平触发简化情况module seqorcombin(rst,clk,d,q); input rst,clk; input d; output q; reg q; always @ (clk or rst)if (!rst)q<=1'b0; elseq<=d; endmodule这是时序逻辑还是组合逻辑?或者你觉得它应该是什么?;

第12页:持续赋值语句综合情况(续5)

过程块-综合结果综合过程中的warning:1. "E:/seqorcombin.v",line 2: Warning,input clk is never used.2. "E:/seqorcombin.v",line 12: Warning,d should be present inthe 'always' condition.

第13页:持续赋值语句综合情况(续6)

过程块-5分频电路的两个边沿触发module divide5error(rst,clk,clk5); input rst,clk; output clk5; reg clk5; reg [2:0] counter; always @(posedge clkornegedge clkor negedge rst)if (!rst)counter <=3'b000; else if(counter==3'b100)counter <=3'b000; else counter <= counter+1; always @(rst or counter)if (!rst) clk5=1'b0; else if(counter==3'b100)clk5=~clk5; endmodule;

第14页:持续赋值语句综合情况(续7)

仿真波形分析
从仿真波形上看,满足5分频要求,但是,综合的电路情况是否同样满足呢?

第15页:持续赋值语句综合情况(续8)

Leonardo工具综合的电路图综合时报告的ERROR:"E:/divide5_error/divide5error.v", line 28:Error, Always block sensitive to both positive andnegative edge of clk and clk can not be synthesized为什么?????(以D触发器说明,上跳沿和下跳沿同时触发可以吗?)always @(posedge clkornegedge clkor negedge rst)if (!rst)q<=1'b0; elseq<=d;

第16页:持续赋值语句综合情况(续9)

过程块-举例分析1module seqorcombin(rst,clk,a,b,c,d,q); input rst,clk; input a,b,c,d; output q; reg q; always @(posedge clk or rst)if (!rst)q<=1'b0; elseq<=(d&a)||(b&~c); endmodule这是时序逻辑还是组合逻辑?或者你觉得它应该是什么?综合时出错信息:"E:/seqorcombin/seqorcombin.v", line 25:Error,Illegalmixing of level and edge triggers;

第17页:持续赋值语句综合情况(续10)

过程块-举例分析2module seqorcombin(rst,clk,a,b,c,d,q); input rst,clk; input a,b,c,d; output q; reg q; always @(posedge clk or negedge rstor a or b or cor d)if (!rst)q<=1'b0; elseq<=(d&a)||(b&~c); endmodule这是时序逻辑还是组合逻辑?或者你觉得它应该是什么?综合时出错信息:"E:/seqorcombin/seqorcombin.v", line 25:Error,Illegal mixing of level and edge triggers;

第18页:过程块中的寄存器类型若在同步块中使用re

过程块中的寄存器类型若在同步块中使用reg,则:

  • 如果在一个时钟周期被赋值并在另一个周期被采样,则以硬件触发器实现。
  • 如果reg还是一个基本输出,它会出现在综合网表中,但不一定是一个硬件触发器。
  • 若在组合块中使用reg,则:
  • 如果reg值随块的任何一个输入的变化而改变,则在综合时不会产生硬件触发器。
  • 如果reg值并不总是随块的输入变化而改变,则综合时会产生一个锁存器。

第19页:寄存器综合情况举例-1

module DFFornet(rst,clk,a,b,c,data_out); input rst,clk; input a,b,c; output data_out; reg data_out; reg data_temp; always @(posedge clk or negedge rst)if (!rst)data_temp<=1'b0; elsedata_temp<=a&b; always @(posedge clk or negedge rst)if (!rst)data_out<=1'b0; elsedata_out<=data_temp|c; endmodule;

第20页:寄存器综合情况举例-1综合后的电路图

寄存器综合情况举例-1综合后的电路图

第21页:寄存器综合情况举例-2

module DFFornet(rst,clk,a,b,c,data_out); input rst,clk; input a,b,c; output data_out; reg data_out; reg data_temp; always @(a or b or rst)if (!rst)data_temp<=1'b0; elsedata_temp<=a&b; always @(posedge clk or negedge rst)if (!rst)data_out<=1'b0; elsedata_out<=data_temp|c; endmodule;

第22页:寄存器综合情况举例-2综合后的电路图

寄存器综合情况举例-2综合后的电路图

第23页:寄存器综合情况举例-3

module DFFornet(rst,clk,a,b,c,data_out); input rst,clk; input a,b,c; output data_out; reg data_out; reg data_temp; always @(a or b or rst)if (!rst)data_temp<=1'b0; elsedata_temp<=a&b; always @(data_temp or c or rst)if (!rst)data_out<=1'b0; elsedata_out<=data_temp|c; endmodule;

第24页:寄存器综合情况举例-3综合后的电路图

寄存器综合情况举例-3综合后的电路图

第25页:寄存器综合情况举例-4

module DFFornet(rst,clk,a,b,c,data_out); input rst,clk; input a,b,c; output data_out; reg data_out; reg data_temp; always @(posedge clk or negedge rst)if (!rst)data_temp<=1'b0; elsedata_temp<=a&b; always @(data_temp or c or rst)if (!rst)data_out<=1'b0; elsedata_out<=data_temp|c; endmodule;

第26页:寄存器综合情况举例-4综合后的电路图

寄存器综合情况举例-4综合后的电路图

第27页:寄存器综合情况举例-5寄存器组/存储器

的综合情况module registers(rst,clk,a,b,c,sel, r_wr_en, data_out); input rst,clk,sel, r_wr_en; input [7:0] a,b,c; output [7:0] data_out; reg [7:0]data_out; reg [7:0]data_temp[2:0]; always @(posedge clk or negedge rst)if (!rst)data_temp[0]<=8'h00; else if(r_wr_en)begindata_temp[0]<=a&b; data_temp[1]<=a&c; data_temp[2]<=c&b; endalways @(posedge clk or negedge rst)if (!rst)data_out<=8'h00; else if(! r_wr_en)data_out<=(sel)?(~data_temp[0]|data_temp[1]):(data_temp[1]|~data_temp[2]); endmodule;

第28页:寄存器组/存储器综合情况举例-5综合后

寄存器组/存储器综合情况举例-5综合后的电路图

第29页:非结构化的for循环

组合逻辑敏感量完整性问题敏感表不完全情况:module sens (a, q, b, sl); input a, b, sl; output q; reg q; always @(sl)beginif (! sl)q = a; elseq = b; endendmodule修改后完全的敏感列表module sensc (q, a, b, sl); input a, b, sl; output q; reg q; always @(sl or a or b)beginif (! sl)q = a; elseq = b; endendmodule!!!!!!描述组合逻辑时:将块内赋值语句右边的变量,条件语句中的条件变量都列入敏感表是很好的描述习惯(但是时钟信号除外)。;

第30页:函数function/任务(续1)

时序逻辑敏感列表敏感表多余:module DFFornet(rst,clk,a,b,data_out); input rst,clk; input a,b; output data_out; reg data_out; always @(posedge clk or negedge rstor a or b)if (!rst)data_out<=1'b0; elsedata_out<=a&b; endmodule修改后完全的敏感列表module DFFornet(rst,clk,a,b,data_out); input rst,clk; input a,b; output data_out; reg data_out; always @(posedge clk or negedge rst)if (!rst)data_out<=1'b0; elsedata_out<=a&b; endmodule在下面的例子,a, b, rst,clk是块的输入;
  • clk用作同步时钟a、b用在过程赋值语句的右边综合报错信息:Error, Illegal mixing of level and edge triggers。描述时序逻辑时:用边沿触发,敏感表里最多一个时钟信号一个复位信号。其他被赋值对象,都会在时钟的触发下,进行刷新。

第31页:组合逻辑反馈环的

持续赋值语句综合情况module orand (out, a, b, c, d, e); input a, b, c, d, e; output out; assign out = e & (a | b) & (c | d);// always@(e or a or b or c or d)// out = e & (a | b) & (c | d); endmodule持续赋值驱动值到net上。因为驱动是持续的,所以输出将随任意输入的改变而随时更新,因此将产生组合逻辑。;

第32页:组合逻辑反馈环的避免(续1)

过程持续赋值module latch_quasi (q, en, d); input en, d; output q; reg q; always @( en)if (en) assign q = d; (不可综合)else deassign q; (不可综合)endmodule综合报错信息:"E:/zzx/alwaysassign.v", line 7:Error,Procedural 'assign' not supported."E:/zzx/alwaysassign.v", line 9:Error,'deassign' not supported.过程持续赋值是在过程块(always或initial)内给一个寄存器数据类型进行的持续赋值。这在大多数综合工具中是非法的。;

第33页:阻塞赋值-非阻塞赋值

可综合条件语句的注意事项1.避免推断出不必要的锁存器:在描述组合逻辑中,锁存器产生的原因(1)if…else语句的配对缺失(2) case语句情况不完整2.优先级的注意3.晚到达信号的优化

第34页:module latch 代码示例

module latch (q, data, enable); input data, enable; output q; reg q; always @( enable or data)if (enable)q = data; 

第35页:综合过程中Warning信息

Warning,q is not always assigned. Storage may be needed..上例综合情况:

第36页:阻塞赋值-非阻塞赋值(续1)

分支完全的条件语句module comcase (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)case ({ a, b})2'b11: e = d; 2'b10: e = ~c; 2'b01: e = 1'b0; 2'b00: e = 1'b1; endcaseendmodulemodule compif (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)if (a & b)e = d; else if (a & ~b)e = ~c; else if(~ a & b)e = 1'b0; else if(~ a & ~b)e = 1'b1; endmodule例中定义了所有可能的选项,综合结果是纯组合逻辑,没有不期望的锁存器产生。;

第37页:阻塞赋值-非阻塞赋值(续2)

分支不完全的条件语句module inccase (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)case ({ a, b})2'b11: e = d; 2'b10: e = ~c; endcaseendmodulemodule incpif (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)if (a & b)e = d; else if (a & ~b)e = ~c; endmodule在上面的例子中,当a变为零时,不对e赋新值。因此e保存其值直到a变为1。这是锁存器的特性。;

第38页:综合过程中Warning信息(续1)

综合过程中Warning信息
Warning,e is not always assigned. Storage may be needed.上例左边case语句不完整的综合情况:

第39页:阻塞赋值-非阻塞赋值(续3)

修改后:加了default-else,形成完全分支条件语句module comcase (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)case ({ a, b})2'b11: e = d; 2'b10: e = ~c; default: e = 'bx; endcaseendmodulemodule compif (a, b, c, d, e); input a, b, c, d; output e; reg e; always @( a or b or c or d)if (a & b)e = d; else if (a & ~b)e = ~c; elsee = 'bx; endmodule综合工具将‘bx作为无关值,因此if语句类似于“full case”,可以进行更好的优化。例中没有定义所有选项,但对没有定义的项给出了缺省行为。同样,其综合结果为纯组合逻辑——没有不期望的锁存器产生。;

第40页:上例左边case语句修改后综合情况

上例左边case语句修改后综合情况:

第41页:同步复位

可综合条件语句的注意事项1.避免推断出不必要的锁存器:在描述组合逻辑中,锁存器产生的原因(1)if…else语句的配对缺失(2)case语句情况不完整2.条件语句的优先级

第42页:同步复位(续1)

if语句modulesingle_if(a, b, c, d, sel, z); input a, b, c, d; input [3:0] sel; output z; reg z; always @(a or b or c or d or sel)beginif (sel[3]) z = d; else if (sel[2]) z = c; else if (sel[1]) z = b; else if (sel[0]) z = a; else z = 0; endendmodulemodulemult_if(a, b, c, d, sel, z); input a, b, c, d; input [3:0] sel; output z; reg z; always @(a or b or c or d or sel)beginz = 0; if (sel[0]) z = a; if (sel[1]) z = b; if (sel[2]) z = c; if (sel[3]) z = d; endendmodule例1.1a单个if语句例1.1b多重if语句注意代码的优先级;

第43页:if语句leonardo工具综合结果

if语句leonardo工具综合结果

第44页:同步复位(续2)

case语句和casez语句的综合情况module case1(a, b, c, d, sel, z); input a, b, c, d; input [3:0] sel; output z; reg z; always @(a or b or c or d or sel)begincasez(sel)//如果换成case(sel),会有什么情况4’b1???: z = d; 4’b?1??: z = c; 4’b??1?: z = b; 4’b???1: z = a; default: z = 1’b0; endcaseendendmodulecasez具有使用无关项的优点,不用列出sel的所有组合。例1.2 case语句;

第45页:casez语句leonardo工具综合结

casez语句leonardo工具综合结果

第46页:换成case的leonardo工具综合结

换成case的leonardo工具综合结果

第47页:同步复位(续3)

多个if分支和CASE语句综合情况

  • case语句通常综合成一级多路复用器,如下图的右边部分所示,而If语句则综合成优先编码的串接的多个两路复用器,如下图的左边部分所示。通常,使用case语句比if语句快。
  • 因此,在处理超过2个分支的if语句时,尽量采用case条件语句.

第48页:

第49页:正确使用过程块来表达组合逻辑和时(续1)

晚到达信号处理设计时通常知道哪一个信号到达的时间要晚一些。这些信息可用于构造HDL,使到达晚的信号离输出近一些。下面的例子中,针对晚到达信号重新构造if和case语句,以提高逻辑性能。

第50页:正确使用过程块来表达组合逻辑和时(续2)

晚到达的数据信号优化处理假如信号b_is_late是晚到达信号,利用单个if语句的多分支和多重if语句的不同优先级,可以使晚到达信号离输出近一些module mult_if_improved(a,b_is_late, c, d, sel, z); input a,b_is_late, c, d; input [3:0] sel; output z; reg z; always @(a orb_is_lateor c or d or sel)beginz = 0; if (sel[0]) z = a; if (sel[2]) z = c; if (sel[3]) z = d; if (sel[1])z = b_is_late; endendmodule单if结构多分支情况module single_if(a,b_is_late, c, d, sel,z); input a,b_is_late, c, d; input [3:0] sel; output z; reg z; always @(a orb_is_lateor c or d or sel)if (sel[1])z = b_is_late; else if (sel[2]) z = c; else if (sel[3]) z = d; else if (sel[0]) z = a; else z = 0; endmodule多重if结构;

第51页:晚到达的数据信号-电路图

晚到达的数据信号-电路图

第52页:正确使用过程块来表达组合逻辑和时(续3)

晚到达的是控制信号如果晚到达信号作为if语句条件分支的条件,也应使这个信号离输出最近。在下面的例子中,CTRL_is _late是晚到达的控制信号,使它离输出最近.优化:module single_if_late(A, C,CTRL_is_late, Z); input [6:1] A; input [5:1] C; inputCTRL_is_late; output Z; reg Z; always @(C or A orCTRL_is_late)// late arriving signal in if conditionif ((C[4] == 1’b1)&&(CTRL_is_late== 1’b0))Z = A[4]; else if (C[1] == 1’b1) Z = A[1]; else if (C[2] == 1’b0) Z = A[2]; else if (C[3] == 1’b1) Z = A[3]; else if (C[5] == 1’b0) Z = A[5]; else Z = A[6]; endmodule;

第53页:优化-尽量资源共享

括号的作用
分割逻辑z = a + b + c + d;Z = (a + b) + (c + d);+b+c+zd+b+cd+zaa

第54页:复杂操作符

非结构化的for循环综合工具处理循环的方法是将循环内的电路结构重复。在循环中包含不变化的表达式会使综合工具花很多时间优化这些冗余逻辑。………//在过程块内for( i =3’b000; i<3’b100; i=i+1)beginsignal1 = signal2;//unchanging statementdata_out(i) = data_in(i);end修改为:………//在过程块内signal1 = signal2;// unchanging statementfor( i =0; i<4; i=i+1)data_out(i) = data_in(i);

第55页:正确使用过程块来表达组合逻辑和时(续4)

函数的综合情况module orand (out, a, b, c, d, e); input a, b, c, d, e; output out; wire out; assign out =forand(a, b, c, d, e); function forand; input a, b, c, d, e; if (e == 1)forand = (a| b) & (c| d); elseforand = 0; endfunctionendmodule!!!!!!!函数没有时序控制,因此综合结果为组合逻辑。函数可以在过程块内或持续赋值语句中调用。下例中的or/and块由持续赋值语句调用函数实现;

第56页:正确使用过程块来表达组合逻辑和时(续5)

任务综合情况module orandtask (out, a, b, c, d, e); input a, b, c, d, e; output out1; reg out1; always @( a or b or c or d or e)orand(out1,a, b, c, d, e); taskorand; input a, b, c, d, e; output out; if (e == 1)out= (a| b) & (c| d); elseout= 1’b0; endtaskendmodule任务一般只在测试基准使用,因为:;
  • 没有时序控制的任务如同函数
  • 带有时序控制的任务不可综合下面是用任务描述的or/and块:

第57页:正确使用过程块来表达组合逻辑和时(续6)

组合逻辑反馈环(feedback)的避免module comb_loop( O, I1,I2); output O; input I1,I2; assign O=(I2)?(I1):(~O|I1); endmodule生成组合逻辑反馈环的实例:综合工具information:Warning: Design containscombinatorial loopthrough net O.;

第58页:O 连续赋值示例

组合逻辑反馈环会导致电路不稳定://assign O=(I2)?(I1):(~O|I1); 初始时刻:I2=1,I1=1则输出O为1; 在T2时刻:I2=0,I1=0,如果第一个或非门的B输入端是旧的O值(1),第一个或非门输出0,则输出O变为0;反馈回第一个或非门B输入端,导致第一个或非门输出1,则输出O又变为1,再反馈回B端,那么到底电路上应该是什么值呢?!!!!!!!!即电路存在不确定性原因:;

第59页:如果逻辑上确实需要反馈,则改为同步反馈

如果逻辑上确实需要反馈,则改为同步反馈。

第60页:module syn_loop 代码示例

组合逻辑反馈环改为时序反馈:module syn_loop( O, I1,I2,clk,rst); output O; input I1,I2,clk,rst; reg O_temp; assign O=O_temp; always@(posedge clk or negedge rst)if (!rst)O_temp<=1'b0; elseO_temp<=(I2)?(I1):(~O_temp|I1); endmodule;

第61页:module syn_loop(续1)

问题:module syn_loop( O, I1,I2,clk,rst); output O; input I1,I2,clk,rst; reg O_temp; assign O=O_temp; always @(rst or I1 or I2 or O_temp)//改成这样,可以否??if (!rst)O_temp<=1'b0; elseO_temp<=(I2)?(I1):(~O_temp|I1); endmodule;

第62页:综合告警!!!Warning

Design containscombinatorial loopthrough net O。!!!!!!!!!!!!在工程中,一般综合后的电路图看不懂是正常的,但是应该注意综合工具的information窗口在综合过程中报告出的所有error,warning信息。上页修改为always @(rst or I1 or I2 or O_temp后综合电路如下:它是组合电路还是时序电路?是否存在组合逻辑反馈环,如果存在,应该怎么修改?问题:答案

第63页:正确使用过程块来表达组合逻辑和时(续7)

阻塞或非阻塞赋值使用的赋值类型依赖于所描述的逻辑类型:

  • 在时序块RTL代码中使用非阻塞赋值–非阻塞赋值保存值直到时间片段的结束,从而可以避免仿真时的竞争情况或结果的不确定性
  • 在组合的RTL代码中使用阻塞赋值–阻塞赋值立即执行

第64页:正确使用过程块来表达组合逻辑和时(续8)

同步复位与异步复位复位是可综合编码风格的重要环节。D触发器中一般都有复位。module sync( q, clk, rst, d); input clk, d, rst; output q; reg q; always @( negedge clk)if (rst)q <= 1’b0; elseq <= d; endmodulemodule async( q, clk, rst, d); input clk, d, rst; output q; reg q; always @( negedge clk or posedge rst)if (rst)q <= 1’b0; elseq <= d; endmodule同步复位异步复位同步复位描述:需要在时钟触发下,当复位信号有效时,进行复位操作;当复位信号无效时,执行该块的其他操作。如果将复位信号作为条件语句的条件,且在第一个分支中进行复位,综合工具可以更容易的识别复位信号。异步复位:在同步块的敏感表中包含复位信号的激活边沿。当复位信号有效时,不需要根据时钟是否触发而进行的复位操作。;

第65页:module async 代码示例

错误的异步复位描述下面的异步复位描述(异步复位和同步块分开)是一种很不好的描述风格,并且有的综合工具不支持。(类似线与问题或者多驱动问题)module async( q, clk, rst, d); input clk, d, rst; output q; reg q; always @( negedge clk)if ( !rst ) q <= d; always @( posedge rst)q <= 1’b0; endmodule综合工具报错信息:line 5: Error, electrical error due tomultiple concurrent assignmentsto 'q'; also line 7.;

第66页:复位信号的时序逻辑

多驱动问题(multiple drive):always @(posedge clk or negedge rst)if(!rst)a<= #DELAY 6'b0; else if(EOB)a<= #DELAY ……; always @(posedge clk or negedge rst)if(b)a<= #DELAY …..;

第67页:正确使用过程块来表达组合逻辑和时(续9)

多驱动问题还是以5分频电路为例:module divide5 (rst,clk,clk5); input rst,clk; output clk5; reg clk5; reg [2:0] counter; always @(rst or counter)if (!rst) clk5=1'b0; else if(counter==3'b100)clk5=~clk5;

第68页:clkor 时序逻辑示例

还是以5分频电路为例(cont.):always @(posedge clkor negedge rst)if (!rst)counter <=3'b000; else if(counter==3'b100)counter <=3'b000; else counter <= counter+1; always @(negedge clkor negedge rst)if (!rst)counter <=3'b000; else if(counter==3'b100)counter <=3'b000; else counter <= counter+1; endmodule;

第69页:仿真波形

(满足5分频占空比为50%的要求)但是综合结果呢?

第70页:module divide5 代码示例

分频电路如果改为以下的描述呢?module divide5 (rst,clk,clk5); input rst,clk; output clk5; reg clk5; reg [2:0] counter1,counter2; wire clk_; assign clk_=~clk; always @(rst or counter1 or counter2)if (!rst) clk5=1'b0; else if((counter1==3'b100)||(counter2==3'b100))clk5=~clk5;

第71页:clk 时序逻辑示例(续1)

always @(posedge clk or negedge rst)if (!rst)counter1 <=3'b000; else if(counter1==3'b100)counter1 <=3'b000; else counter1 <= counter1+1;else if(counter2==3'b100)counter2 <=3'b000; else counter2 <= counter2+1; endmodule;

第72页:

第73页:寄存器reg被综合为D触发器(续1)

资源共享-一般情况资源共享是指多节代码共享一组逻辑。好处,可以节省芯片面积.例如:always @( a or b or c or d)if (a)out = b + c; elseout = b + d; 没有资源共享资源共享资源共享与所用综合工具的算法有关。但通常,即使工具能共享资源,表达式也必须在同一个always块中的同一个条件语句中。;

第74页:最佳写法资源共享可以由RTL代码控制

。例如,可以改变编码风格为强制资源共享。if (a)out = b + c;elseout = b + d;原始代码强制资源共享方式temp = a ? c : d;out = b + temp;或者out = b + (a ? c : d);

第75页:寄存器reg被综合为D触发器(续2)

复杂操作符

  • 大多数工具可以将它映射为一个乘法器。
  • 专用宏单元库中可能有乘法器。宏单元库中的元件的复杂程度要比常规单元库高。
  • 宏单元库可以包含部分可重用设计,如FIFO,加法器,减法器(各种结构),移位寄存器,计数器和解码器等。
  • 宏单元库还可以包括用户自定义的可重用块,由用户自己设计并综合。复杂操作符是可以被识别为高层操作并被直接映射到一个向量库内以存在单元的操作。例如:out=a*b;

第76页:寄存器reg被综合为D触发器(续3)

总结
综合工具不能胜任的工作
  • 复杂的时钟方案
  • 组合逻辑反馈循环和脉冲发生器
  • 存储器,IO
  • 专用宏单元
  • 总做得和你一样好

第77页:综合工具善于优化组合逻辑

。但设计中有很大一部分不是组合逻辑。

  • 综合工具不能很好地处理复杂时钟。
  • 综合工具不易实现脉冲产生逻辑,如单个脉冲,或结果依赖于反馈路径延迟的组合反馈逻辑。对这种情况,插入延迟元件使一个信号推迟到达的效果并不好。
  • 不能用综合产生大块存储器,因为综合工具会用flip-flop实现。
  • 不是所有的综合工具都能很好地从工艺库里挑选择大的单元或宏单元,这需要用户人工实例化。一些宏单元,例如大的结构规则的数据通路元件,最好使用生产商提供的硅编译器产生。
  • 综合工具不保证产生最小结果。通常综合结果不如人工结果,只要你有足够的时间。

第78页:寄存器reg被综合为D触发器(续4)

总结
Verilog语法口诀
  • Reg与wire变量类型及其对应的电路模型;
  • 连续赋值、阻塞赋值、非阻塞赋值语句区别;
  • 时序、组合逻辑电路的Verilog描述,always@(敏感量)完整性;
  • 语句、块并行执行的理解。