语法详细讲解强制激励ppt课件_第1页
语法详细讲解强制激励ppt课件_第2页
语法详细讲解强制激励ppt课件_第3页
语法详细讲解强制激励ppt课件_第4页
语法详细讲解强制激励ppt课件_第5页
已阅读5页,还剩115页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、语法详细讲解强制激励,在一个过程块中,可以用两种不同的方式对信号变量或表达式进行连续赋值。 过程连续赋值往往是不可以综合的,通常用在测试模块中。 两种方式都有各自配套的命令来停止赋值过程。 两种不同方式均不允许赋值语句间的时间控制。 assign和deassign 适用于对寄存器类型的信号(例如:RTL级上 的节点或测试模块中在多个地方被赋值的信号)进行赋值。 initial begin #10 assign top.dut.fsml.state_reg = init_state;,#20 deassign top.dut.fsml.state_reg; end force 和 release

2、 用于寄存器类型和网络连接类型(例如:门级扫描寄存器的输出)的强制赋值,强制改写其它地方的赋值。 initial begin # 10 force top.dut.counter.scan_reg.q=0; # 20 release top.dut.counter.scan_reg.q; end 在以上两个例子中,在10到20 这个时间段内,网络或寄存器类型的信号被强制赋值,而别处对该变量的赋值均无效。 force的赋值优先级高于assign。 如果先使用assign,再使用force对同一信号赋值,则信号的值为force所赋 的值,,语法详细讲解强制激励,语法详细讲解字符串,语法详细讲解强制

3、激励,语法详细讲解强制激励,当执行release后,则信号的值为assign所赋 的值。 如果用force对同一个信号赋了几次值,再执行release,则所有赋的值均不再存在。 可以对信号的某(确定)位、某些(确定)位或拼接的信号,使用force和release赋值;但不能对信号的可变位使用force和release 来赋值。 不能对寄存器类型的信号某位或某些位使用 assign 和deassign 来赋值。,语法详细讲解强制激励,语法详细讲解建立时钟,虽然有时在设计中会包含时钟,但时钟通常用在测试模块中。下面 三个例子分别说明如何在门级和行为级建立不同波形的时钟模型。 例1 简单的对称方波时

4、钟:,语法详细讲解建立时钟,reg clk; always begin #period/2 clk=0; #period/2 clk=1; end,reg go; wire clk; nand #(period/2) ul (clk,clk,go); initial begin go=0; #(period/2) go=1; end,注:在有些仿真器中,如果设计所用的时钟是由与其相同抽象级别的时钟模型产生的,则仿真器的性能就能得到提高。,例2简单的带延迟的对称方波时钟:,语法详细讲解建立时钟,reg clk; initial begin clk=0; #(period) forever #(p

5、eriod/2) clk=!clk end,reg go; wire clk; nand #(period/2) ul (clk,clk,go); initial begin go=0; #(period) go=1; end,注:这两个时钟模型有些不同,行为描述的模型延迟期间一直是低电平,而门级描述的模型开始延迟有半个周期是不确定的。,语法详细讲解建立时钟,例3. 带延迟、头一个脉冲不规则的、占空比不为1的时钟:,语法详细讲解建立时钟,reg clk; initial begin #(period+1) clk=1; #(period/2-1) forever begin #(period/

6、4) clk=0; #(3*period/4) clk=1; end end,reg go; wire clk; nand #(3*period/4,period/4) ul(clk,clk,go); initial begin #(period/4+1) go=0; #(5*period/4-1) go=1; end,注:这两个时钟模型也有些不同,行为描述的模型一开始就有确定的电平,而门级描述的模型有延迟开始时电平是不确定的。,语法详细讲解怎样使用任务,mocule bus_ctrl_tb reg 7:0 data; reg data_valid, data_rd; cpu ul(data_

7、valid,data,data_rd); initial begin cpu_driver(8b0000_0000); cpu_driver(8b1010_1010); cpu_driver(8b0101_0101); end task cpu_driver;,语法详细讲解怎样使用任务,语法详细讲解怎样使用任务,input 7:0 data_in; begin #30 data_valid=1; wait(data_rd=1); #20 data=data_in; wait(data_rd=0); #20 data=8hzz; #30 data_valid=0; end endtask,语法详

8、细讲解怎样使用任务,语法详细讲解怎样使用任务,endmodule 在测试模块中使用任务可以提高程序代码的效率,可以进行多次重复操作。,语法详细讲解怎样使用任务,wait,wait,wait,wait,data1,data2,data3,data4,cpu_data,clk,data_valid,data_read,read_cpu_state,语法详细讲解存储建模,目标 学会使用Verilog进行存储建模。 学会在Verilog中进行双向口建模。,语法详细讲解存储建模,存储设备建模必须注意以下两个方面的问题: 声明存储容量的大小。 提供对内容的访问权限,例如: 只读 读写 同步读写 多次读,同

9、时进行一次写 多次同步读写,同时提供一些方法保证一致性,语法详细讲解存储设备建模,myrom.v timescale 1ns/10ps module myrom(read_data,addr,read_en_); input read_en_; input 3:0 addr; output 3:0 read_data; reg 3:0 read_data; reg 3:0 mem 0:15; initial $readmemb(“my_rom_data”,mem); always (addr or read_en_) if(!read_en_) read_data=memaddr; endmo

10、dule,语法详细讲解简单ROM建模,my_rom_data 0000 0101 1100 0011 1101 0010 0011 1111 1000 1001 1000 0001 1101 1010 0001 1101,ROM的数据存储在另外的一个独立的文件中,语法详细讲解简单ROM建模,上面所示的ROM模型中使用二维的存储寄存器来定义存储容量。ROM中的数据保存在一个独立的文件中,如上面的右边所示。这是一种保存ROM数据的通用的方法,它可以使数据和ROM模型分开。,语法详细讲解简单RAM建模,timescale 1ns/1ns module mymem(data,addr,read,wri

11、te); inout 3:0 data; inout 3:0 addr; input read, write; reg 3:0 memory 0:15; /4 bits, 16 words /read assign data=read? memoryaddr:4bz; /write always (posedge write) memoryaddr=data; endmodule,RAM模型比ROM模型稍微复杂,因为它必须具有读写能力,而进行读写时通常使用相同的数据总线,这就需要新技术来处理双向总线。当读出口没有被激活时,RAM模型不再激励总线,如果此时的总线写入变量也没有被激活,则总线进入高

12、阻状态,这就避免了RAM中的读写竞争。,上述模型是可综合的,但是许多工具只产生一系列的寄存器,这一般就需要更大的空间,从而比实际的存储器的价格更昂贵。,语法详细讲解简单RAM建模,例: module scalable_ROM(mem_word,address); parameter addr_bits=8; /size of address bus parameter wordsize=8; /width of a word parameter words=(1addr_bits); /size of mem output wordsize:1 mem_word; /word of memor

13、y input addr_bits:1 address; /address bus reg wordsize:1 mem 0:words-1; /mem declaration /output one word of memory wire wordsize:1 mem_word=memaddress; endmodule,语法详细讲解容量可变的存储器建模,语法详细讲解容量可变的存储器建模,上述的例子演示了怎样通过设置字长和地址位数来定义一个只读存储设备。 在上例中,存储字的范围从0开始的,而不是从1开始,这是因为内存是直接通过地址线定位的,同样地,也可以用下面的方法来定义内存和定位: reg

14、 wordsize:1 mem 1:words; /memory starts at word 1 /address must be incremented to address all words in memory wire wordsize:1 mem_word=memaddress+1;,可以通过使用一个循环或系统任务来载入存有数据的整个存储器。 使用循环把值赋给存储数组。 for(i=0;imemsize;i=i+i) / initialize memory memai=wordsize1b1; 调用$readmem系统任务。 /load memory data form a fil

15、e $readmemb(“mem_file.txt”,mem);,语法详细讲解载入存储设备,语法详细讲解怎样使用双向口,使用inout关键字声明双向口。 inout 7:0 databus; 使用双向口需要遵循下面的规则: 一个inout口只能声明为网络类型,而不能是寄存器类型的。 因此仿真器能确定多个激励源的最终值。 在设计中,每次只能激活inout的一个方向。 例如:当使用总线读RAM中的数据时,同时又向RAM模 型的双向数据总线写数据,就会产生逻辑竞争,导致总 线脱离。 必须为inout口设计控制逻辑,用来保证正确的操作。,语法详细讲解怎样使用双向口,注: 可以声明一个inout口,用来

16、输入或输出数据。inout口默认为网络类型,不可以对网络类型的数据进行过程赋值,但可以在过程块外对寄存器数据类型进行连续赋值,或者把它与元器件相连。 必须为inout口设计控制逻辑,用来保证正确的操作。当把inout口做为输入口时,必须使输出逻辑失效。,使用元器件,语法详细讲解双向口建模,en_a_b,en_b_a,bus_a,bus_b,module bus_xcvr (bus_a,bus_b,en_a_b,en_b_a); inout bus_a,bus_b; input en_a_b,en_b_a; bufifl b1(bus_b,bus_a,en_a_b); bufifl b2(bus

17、_a,bus_b,en_b_a); /结构模块逻辑 endmodule,当en_a_b=1时,元器件b1激活,bus_a的值传到bus_b上,当en_b_a=1时,元器件b1激活,bus_b的值传到bus_a上,语法详细讲解双向口建模,注:在上页的例子中,使用了en_a_b和en_b_a 来控制元器件bufifl,如果进行同时控制,则得不到预期的结果。,使用连续赋值,en_a_b,en_b_a,bus_a,bus_b,module bus_xcvr (bus_a,bus_b,en_a_b,en_b_a); inout bus_a,bus_b; input en_a_b,en_b_a; assi

18、gn bus_b=en_a_b? bus_a:bz; assign bus_a=en_b_a? bus_b:bz; /结构模块逻辑 endmodule,当en_a_b=1时,bus_a的值传到bus_b上,当en_b_a=1时,bus_b的值传到bus_a上,语法详细讲解双向口建模,注:在assign语句中,通过en_a_b和en_b_a控制bus_a与bus_b之间的数据交换。 如果进行同时控制,则得不到预期的结果。,语法详细讲解双向口建模,存储口建模,语法详细讲解双向口建模,测试模块,RAM单元,数据总线,数据 寄存 器,rd,wr,module ram_cell(databus,rd.w

19、r); inout databus; input rd,wr; reg datareg; assign databus=rd? datareg:bz; always (negedge sr) datareg=databus; endmodule,当rd等于1时datareg的值被赋给databus,当wr的下降沿到达时,databus的值被写入datareg,注:上页存储单元在wr的下降沿到达时存入数据。上页模块在 wr处于高电平时,通过数据总线写入数据,但必须保证wr的高电平维持时间长于数据的写入时间。 在rd处于高电平时,上述存储单元通过数据总线读出数据。由于此模型为单口存储模型,因此wr

20、和rd不能同时为高电平,否则就得不到预期的结果。,语法详细讲解双向口建模,目标 学会怎样定义或调用任务和函数。 学会怎样使用命名块。 学会怎样使命名块和任务失效。 熟悉有限状态机及怎样进行有限状态机显式建模。,语法详细讲解第十七部分 Verilog中的高级结构,可以通过把代码分成小的模块或者使用任务和函数,来把一项任务 分成许多较小的、易于管理的部分,从而提高代码的重用性。 任务 一般用于执行调试操作,或者行为的描述硬件 可以包含时间控制(# delays, , wait) 可以包含input, output 和 inout参数 可以调用其他的任务或函数 函数 一般用于计算,或者用来代替组合逻

21、辑 不能包含任何延迟;函数在零时间执行 只能使用input参数,但可以通过函数名来返回一个值。 可以调用其他的函数,但不可以调用任务,语法详细讲解第十七部分 Verilog中的高级结构,注: 必须在模块内调用任务和函数。 在任务和函数中不能声明连线类型的变量。 所有的输入和输出都是真正的本地寄存器类型的数据。 只有当任务或函数调用并执行完后,才能有返回值。例如:当任务或函数中包含一个forever循环时,就不可能有返回值。,语法详细讲解第十七部分 Verilog中的高级结构,语法详细讲解Verilog 任务,下面的任务含有时间控制和一个输入,并且指向一个模块变量,但是不包含输出、总线和内部变量

22、,不显示任何内容。 时间控制中使用的信号(例如 clk)不必是任务的输入,这是因为输入值只向任务内部传递一次。 module top; reg clk, a, b; DUT u1(out, a, b, clk); always #5 clk=!clk; task neg_clocks; input 31:0 number_of_edges; repeat(number_of_edges),语法详细讲解整数和实常数,(negedge clk); endtask initial begin clk=0; a=1; b=1; neg_clocks(3); /任务调用 a=0; neg_clocks(

23、5); b=0; end endmodule 主要特征: 任务调用是通过在Verilog模块中写入任务名来实现的。 任务中可以包含input, output和inout参数。,语法详细讲解Verilog 任务,传递给任务的参数与任务I/O声明参数的顺序相同。虽然传递给任务的参数名可以和任务内部I/O声明的参数名相同,但是为了提高任务的模块化程度,传递给任务的参数名通常是唯一的,而不使用与任务内部I/O声明的参数名相同的参数名。 在任务中可以使用时间控制。 在Verilog中,任务定义了一个新的范围。 使用关键字disable禁止任务。 注意:不要在程序的不同部分同时调用同一个任务。这是因为任务

24、只有一组本地变量,同时调用两次将会导致错误。这种情况通常发生在使用时间控制的任务中。 在任务或函数中,应给在父模块中声明的变量加注释。若在其它模块中调用任务或函数,任务和函数中所使用的变量必须包含在输入/输出口列表中。,语法详细讲解Verilog 任务,下面模块中的任务含有一个双口总线和一个内部变量,但是没有输入、输出和定时控制,没有引用本模块的变量,不显示任何内容。 在任务调用时,任务参数(口)类型被视为内部寄存器类型。 parameter MAX_BITS=8; reg MAX_BITS:1 D; task reverse_bits; inout 7:0 data; /双口总线被视为寄存器

25、类型! integer K; for (k=0; kMAX_BITS; K=K+1) reverse_bits MAXBITS (K+1)=dataK; endtask always (posedge clk) reverse_bits (D); ,语法详细讲解Verilog 任务,下面模块中的任务含有输入、输出、时间控制和一个内部变量,并且引用了一个本模块的变量,但是没有输出,不显示任何内容。 任务调用时的参数顺序应与任务定义中声明的顺序相同。 module mult(clk, a, b, out, en_mult); input clk, en_mult; input 3:0 a, b;

26、output 7:0 out; reg 15:0 out; always (posedge clk) multme(a, b, out); /任务调用,语法详细讲解Verilog 任务,task muotme; /任务定义 input 3:0 xme, tome; output 7:0 result; wait (en_mult) result=xme*tome; endtask endmodule,语法详细讲解Verilog 任务,module orand(a, b, c, d, e, out); input 7:0 a, b, c, d, e; output 7:0 out; reg 7:

27、0 out; always (a or b or c or d or e) out=f_or_and(a, b, c, d, e); /函数调用 function 7:0 f_or_and; input 7:0 a, b, c, d, e; if(e=1) f_or_and=(a|b) endfunction endmodule,语法详细讲解Verilog 函数,虽然函数不能包含定时控制,但是可以在包含定时控制的过程块中调用函数。 在上述函数中使用了函数名f_or_and作为寄存器类型的变量。 要点 函数定义不能包含定时控制语句。 函数必须含有输出,但不能含有输出和总线口; 一个函数只能返回一

28、个值,该值的变量名与函数同名,数据类型默认为reg类型。 传递给函数参数的顺序与函数输入参数声明的顺序相同。 函数定义必须包含在模块定义之内。 函数不能调用任务,但任务可以调用函数。 函数使Verilog有更广阔的适用范围。,语法详细讲解Verilog 函数,虽然函数只能返回一个值,但是它们的返回值可以直接的赋给一个信号拼接,从而使它们有多个输出。 o1, o2, o3, o4=f_or_and(a, b, c, d, e);,语法详细讲解Verilog 函数,语法详细讲解命名块,可以通过在关键字begin或fork后加上:块名来给块命名。 module named_blk; begin :s

29、eq_blk end fork : par_blk join endmodule 可以在命名块中声明本地变量。 可以使用disable禁止命名块。,注意: 命名块使Verilog有更广阔的适用范围。 命名块的使用缩短了仿真的时间。,语法详细讲解命名块,语法详细讲解禁止命名块和任务,module do_arith(out, a, b, c, d, e, clk, en_mult); input clk, en_mult; input 7:0 a, b, c, d, e; output 15:0 out; reg 14:0 out; always (posedge clk) begin : ari

30、th_block /*命名块* reg 3:0 tmp1, tmp2; /*本地变量* tmp, tmp2=f_or_and(a, b, c, d, e); / 函数调用 if(en_mult) multme(tmp1, tmp2, out); /任务调用 end always (negedge en_mult) begin /停止计算 disable multme; /*禁止任务的执行* diable arith_block; /*禁止命名块的执行* end /在此定义任务和函数 endmodle,注意: disable语句用来终止命名块或任务的执行,因此可以在执行所有的语句前,就能从命名块

31、或任务的执行中返回。 语法: disable 块名 或 disable 任务名 禁止执行命名块或任务后,所有在事件队列中安排的事件都将被删除。 在综合中一般不支持disable语句。 在上页的例子中,只禁止命名块也可以得到预期的结果:命名块中所有的事件、任务和函数的执行都将被取消。,语法详细讲解禁止命名块和任务,语法详细讲解有限状态机(FSM),隐式FSM: 不需要状态寄存器 仿真更加有效 只能很好的处理线形状态改变 大部分综合工具不支持隐式FSM,state 1,state 2,state 3,state 4,语法详细讲解编译引导语句,显式FSM: 结构更加复杂 可以很方便的用来处理默认状态

32、 能够处理复杂的状态改变 所有的综合工具均支持显式FSM,语法详细讲解有限状态机(FSM),state A,state A,state A,state A,state A,注意: 在隐式 FSMs 中,无论什么时候在一个时钟周期内写数据和在在另一个时钟周期内读数据,都会创建寄存器。 所有的 FSMs 都必须能复位,状态改变必须与一个单一的时钟信号同步。 一般的,如果状态改变比较简单,又定义的比较好,而且综合工具支持隐式状态机,就可以使用隐式类型。如果状态改变比较复杂,最好使用显式类型,这样会更加有效。 隐式状态机应属于行为级,而不应属于RTL级,代码中主要包含循环、嵌入的定时控制,有时也含有命

33、名事件、wait 和 disable 语句。因此,综合中一般不支持隐式机。,语法详细讲解有限状态机(FSMs),语法详细讲解Verilog 函数,要返回一个矢量值(超过一个位宽),可以在函数名前声明变量的位宽。在函数中,将语句放在 begin 和 end 块中。 在函数中无论多少次对函数名进行赋值,值只返回一次。下面的函数中声明了一个内部整型变量。 module foo; input 7:0 loo; output 7:0 goo; /可以从连续赋值中调用函数 wire 7:0 goo=zero_count(loo); function 3:0 zero_count; input 7:0 in

34、_bus;,语法详细讲解Verilog 函数,integer I; begin zero_count=0; for(I=0; I8; I=I+1) if(!in_busI) zero_count=zero_count+1; end endfunction endmodule,可以声明函数的返回值的类型为 integer、real 或 time, 可以在任何表达式中调用函数。 module checksub(neg, in_a, in_b); output neg; reg neg; function integer_subtr; input 7:0 in_a, in_b; subtr=in_a

35、-in_b; /结果可能是负数 endfunction always (a or b) if(subtr(a, b)0) neg=1; else neg=0; endmodule,语法详细讲解Verilog 函数,可以给返回变量的每一位赋值,还可以参数化函数的大小、函数口、甚至函数的行为。 parameter MAX_BITS=8; reg MAX_BITS:1 D; function MAX_BITS:1 reverse_bits; input 7:0 data; integer K; for(K=0; KMAX_BITS; K=K+1) reverse_bits MAX_BITS-(K+1

36、)=dataK; endfunction always (posedge clk) D=reverse_bits(D); ,语法详细讲解Verilog 函数,语法详细讲解显式有限状态机,module exp(out, datain, clk, rst); input clk, rst, datain; output out; reg out; ret state; always (pasedge clk or posedge rst) if(rst) state, out=2b00; else case(state) 1b0: begin out=1b0; if(!datain) state=

37、1b0; else state=1b1; end 1b1 begin,状态变量,语法详细讲解显式有限状态机,case语句,out=datain; state=1b0; end default: state, out=2b00; endcase endmodule 注: 可以在过程块中使用一个单一的时钟沿和一个 case 语句来描述一个显式状态机。 必须规定一个状态变量,用来定义状态机的状态。 要改变当前的状态,必须改变状态变量的值,状态变量的值的改变要与时钟沿同步。 最好为通常不会发生的状态规定默认动作。,语法详细讲解显式有限状态机,转到下一个状态,默认状态指针,module imp(out,

38、 datain, clk, rst); output out; reg out; input clk, datain, rst; always (rst) /协同复位方法 if (rst) assing out=1b0; else begin deassign out; disable seq_block; /返回到初始状态 end always (posedge clk),语法详细讲解隐式有限状态机,begin: seq_block out=1b0; if(!datain) /状态一:输出零 disable seq_block; (posedge clk) /状态二:输出第二位 out=da

39、tain; end endmodule,语法详细讲解隐式有限状态机,注意: 可以在过程块使用多个时钟沿(一个状态一个)、条件语句、循环语句、disable语句来描述隐式FSM。 不必定义一个状态变量。 若没有强制状态重复(例如:在循环语句或disable语句中强制状态重复),当下一个激活时钟沿到达时,状态改变。下一个装态将由条件语句决定。 在隐式状态机中,很难规定一个默认动作。,语法详细讲解隐式有限状态机,目标 学会怎样创建逻辑使用的用户定义的原语。 用户定义的原语 (UDP) 的行为与嵌入的 Verilog 原器件相似,可以用一个表格来定义它的功能。,语法详细讲解第十八部分 用户定义的原语,

40、在 Verilog 结构模型中,可以使用: 二十多个门级原器件。 用户定义的原语。 UDP 可用于ASIC 库单元设计和小规模芯片和中规模芯片设计。 可以使用 UDP 扩大预定义原器件的范围。 UDP 是自包含的, 不能调用其他的模块。 UDP 既可以用来代替时序逻辑元件,也可以代替组合逻辑元件。 使用真值表来描述 UDP 的行为。 调用 UDP 的方式与调用嵌入的原器件的方式相同。,语法详细讲解什么是UDP?,注: UDP 是一种很好的代替逻辑方式。 在嵌入原器件中,输入中包含的 x 不能在输出时自动转变成 x,而在 UDP 中则不会出现此种情况。 UDP 可以代替许多原器件逻辑。另外,UD

41、P 的仿真时间和内存需要大大低于运行分立原器件。如果仿真工具合适,相同逻辑的行为模型甚至可以更快。,语法详细讲解什么是UDP?,UDP 只能有一个输出端,而且必须是端口的说明列表的第一项。 UDP 可以有多个输入端,最多允许有 10 个。 UDP 所有端口变量必须是标量,不允许使用双向端口。 UDP 不支持 Z 逻辑值。 在仿真的开始,UDP 的输出可以使用 initial 语句初始化为一个已知值。 UDP 不能被综合。,语法详细讲解特征,注: UDP 只能有一个输出。如果设计时的输出多于一个,则需要把其它的原器件连接到 UDP 输出,或同时使用多个 UDP。 UDP 输入端最多可以有 10

42、个,但是当输入的个数多于 5 个时,内存的需要将大大的增加。下页表列出了输入数目不同时,每个输入所需要的内存。,语法详细讲解特征,语法详细讲解特征,组合逻辑示例:2-1 多路器,语法详细讲解示例,primitive multiplexer(o, a, b, s); output o; input s, a, b; table / a b s : o 0 ? 1 : 0; 1 ? 1 : 1; ? 0 0 : 0; ? 1 0 : 1; 0 0 x : 0; 1 1 x : 1; endtable endprimitive,原语名,输出端口必须为第一个端口,注: 在模块外定义 UDP 。 如果在

43、表中没有规定输入组合,将输出 x。 表的列中元素的顺序应与端口列表中的一致。 表中的 ?的意义是:重复的输入 0,1或 x ;逻辑值。 表中开始两行表示:当 s等于 1 时,不管 b 如何取值,输出 o 将与 输入 a 保持一致。 表中的下两行表示:当 s 等于 0 时,不管 a 如何取值,输出 o 将与输入 b 保持一致。 表中 的最后两行使此器件更加的全面、准确。它们表示:当输入 a 和 b 的逻辑值相同时,如果 sel 等于 x,则输出 o 的值 将与输入 a 和 b 的值相同。这种行为不能使用 Verilog 嵌入原器件进行建模。UDP 将 x 作为实际的未知值,而不是 Verilog

44、 值来进行处理,使其比嵌入原器件更加准确。,语法详细讲解示例,可以仅使用两个 UDP 设计全加器。 / 全加器进位实现部分 primitive U_ADDR2_C(CO, A, B, CI); output CO; input A, B, CI, table / A B CI : CO 1 1 ? : 1; 1 ? 1 : 1; ? 1 1 : 1; 0 0 ? : 0; 0 ? 0 : 0; ? 0 0 : 0; endtalbe endprimitive,语法详细讲解组合示例:全加器,/全加器求和实现部分 primitive U_ADDR2_S(S, A, B,CI); output S;

45、 input A, B, CI; table / A B CI : S 0 0 0 : 0; 0 0 1 : 1; 0 1 0 : 1; 0 1 1 : 0; 1 0 0 : 1; 1 0 1 : 0; 1 1 0 : 0; 1 1 1 : 1; endtable endprimitive,语法详细讲解组合示例:全加器,若使用 UDP 设计全加器,仅需要两个 UDP; 而使用 Verilog 嵌入原器件,则需要 5 个Verilog 嵌入原器件。 大量使用全加器时,这将大大减少内存的需要。 事件的数目将大大降低。 ?代表 0,1或 x。,语法详细讲解组合逻辑示例:全加器,primitive l

46、atch(q, clock, data); output q; reg q; input clock, data; initial q=1b1; table / clock data current next / state state 0 1 : ? 1; 0 0 : ? 0; 1 ? : : -; endtable endprimitive,语法详细讲解级触发时序逻辑示例:锁存器,注意此寄存器的用法,此寄存器用来存储。,输出初始化为 1b1.,? 表示无须考虑输入和当前状态的值,注: 锁存器的动作行为如下: 当时钟信号为 0时,输入数据的值直接传给输出。 当时钟信号为1时,输出保持当前状态

47、不变。 next state 栏中的 “-” 表示输出保持不变。 输出必须定义为寄存器类型,用来保存前一个状态。 initial q=1b1; 是时序 UDP 的初始化语句。使用此语句可以在仿真的开始对输出进行赋值。 在实际的部件模型中,很少使用初始赋值。但在测试 UDP 的功能时,初始赋值相当有用。,语法详细讲解级触发时序逻辑示例:锁存器,primitive d_edge_ff (q, clk, data); output q; input clk, data; reg q; table / clk dat state next (01) 0 : ? : 0; (01) 1 : ? : 1;

48、 (0 x) 1 : 1 : 1; (0 x) 0 : 0 : 0; (x1) 0 : 0 : 0; (x1) 1 : 1 : 1;,语法详细讲解边沿敏感的时序逻辑示例:D 触发器,/ 忽略时钟的下降沿 (?0) ? : ? : -; (1x) ? : ? : -; / 忽略时钟稳定时的数据改变 endtable endprimitive 在大多数情况下,可以在任何表入口语句中规定一个输入过渡。 如果规定了任何输入过渡,则必须规定所有输入的所有过渡。,语法详细讲解边沿敏感的时序逻辑示例:D 触发器,建模类型概述 在任何时候,如果输出直接由当前的输入组合决定,则此逻辑为组合逻辑。 如果逻辑中具有

49、记忆功能,则此逻辑为时序逻辑。在任何给定的时刻,如果输出不能由输入的状态确定,则此逻辑具有记忆功能。,语法详细讲解第十九部分 Verilog综合建模类型,综合工具一般不支持下面的 Verilog 结构: initial 一些循环语句: repeat forever while for 的非结构用法 一些数据类型 event real time,语法详细讲解不受支持的 Verilog 结构,UDPs forkjoin 块 wait 过程连续赋值语句 assign 和 deassign force 和 release 一些操作符 = = = != =,语法详细讲解不受支持的 Verilog 结构,

50、两个边沿的任一个 过程块到达所有输入信号的任一个边沿产生组合逻辑。此块称为组合块。 always (a or b) / 实现与门 y=a,语法详细讲解过程块,同步块也可能对异步复位信号的改变敏感。 always (posedge clk or negedge rst_) if(!rst_) q=0; else q=d;,语法详细讲解过程块,当在同步块中使用 reg 类型的信号变量时: 如果此信号变量在一个时钟周期中被附值,而在另一个时钟周期中创建了其实例,则此信号变量仅作为硬件寄存器使用。 如果此信号变量也是基本输出,则其将显示在综合列表中,但不一定是硬件寄存器。 否则,信号可以被优化掉。 当

51、在组合块中使用 reg 类型的信号变量时: 如果当块的任何输入的值改变时,此信号变量的值也随之改变,则此信号变量在综合输出中并不属于硬件寄存器。 如果当块的任何输入的值改变时,此信号变量的值并一定改变,则此信号变量在综合输出中属于锁存器。,语法详细讲解过程块中寄存器类型的信号变量,同步寄存器示例 在下面的例子中,rega 仅用作临时存储器,因此它被优化掉。 module ex1reg(d, clk, q); input d, clk; output q; reg q, rega; always (posedge clk) begin rega=0; if(d) rega=1; q=rega;

52、end endmodule,语法详细讲解寄存器,在下面的例子中,两个时钟沿包含两个存储元素,因此 rega 未被优化掉。 module ex2reg(d, clk, q); input d, clk; output q; reg q, rega; always (posedge clk) begin rega=0; if(d) rega=1; end,语法详细讲解寄存器,always (posedge clk) q=rega; endmodule 注:在后面的例子中,块执行的顺序是不确定的,因此 q 可以获得 在前一个周期中赋给 rega 的值。,语法详细讲解寄存器,组合寄存器示例 在下面的两

53、个例子中,rega 是一个临时变量且被优化掉。 在下面的例子中,y和rega 不断被赋新值;因此,下例是一个纯的组合逻辑。 module ex3reg(y, a, b, c); input a, b, c; output y; reg y, rega; always (a or b or c) begin,语法详细讲解寄存器,if(a end endmodule 在下面的例子中,rega 只是有时被赋新值;因此此例是一个以 y 作为输出的锁存器。,语法详细讲解寄存器,moudule ex4reg(y, a, b, c); input a, b, c; output y; reg y, rega

54、; always (a or b or c) begin if(a end endmodule,语法详细讲解寄存器,在下面的例子中,a、b 和 sl 均是块的输入。 在两个例子中, sl 均为 always 块的条件。 在第二个例子中, a 和 b 也用作always 块的条件。 不完整敏感列表: module sens(a, q, b, sl); input a, b, sl; output q; reg q; always (sl) begin,语法详细讲解敏感列表,if(!sl) q=a; else q=b; end endmodule 完整敏感列表: module sens(q, a,

55、 b, sl); input a, b, sl; output q;,语法详细讲解敏感列表,reg q; always (sl or a or b) begin if(!sl) q=a; else q=b; end endmodule 注:在敏感列表中最好包括所有的输入。对于不完整列表,不同的综合工具处理的方法不同:一些综合工具认为不完整列表是不合,语法详细讲解敏感列表,法的,而其他的综合工具则发出警告并将其当作完整列表处理。因此,综合输出可能与 RTL 描述有所不同。,语法详细讲解敏感列表,在进行连续赋值时,输入的任何改变都将导致输出的同步更新。 module orand(out, a, b

56、, c, d, e); input a, b, c, d, e; output out; assign out=3 endmodule,语法详细讲解连续赋值,过程连续赋值是在过程块(always 和 initial 块)内部对寄存器类型的数据进行的连续赋值。 module latch_quasi(q, en, d); input en, d; output q; reg q; always (en) if(en) assign q=d; else deassign q; endmodule,语法详细讲解过程连续赋值,大部分综合工具都能处理指令。 可在 Verilog 语句之间嵌入指令,Veri

57、log 仿真器将忽略嵌入的指令,但在综合工具编译时,它们是有意义的。 不同的综合工具有不同的指令语法,当它们使用指令的目的都是优化 RTL 代码。 下面给出了一部分 Cadence 综合工具中支持的综合指令的列表,它们与其他综合工具(例如:Synopsys 设计编译器)中的指令非常相似。 /ambit synthesis on /ambit synthesis off /ambit synthesis case=full、parallel、mux,语法详细讲解综合指令,结构指令 /ambit synthesis architecture=cla or rpl 有限状态机指令 /ambit synthesis enum xyz /ambit synthesis stat_vector sig state_vector_flag 注:指令中通常包括综合工具或公司的名称,例如:上面指令中的am

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论