第七讲 verilog语法_第1页
第七讲 verilog语法_第2页
第七讲 verilog语法_第3页
第七讲 verilog语法_第4页
第七讲 verilog语法_第5页
已阅读5页,还剩111页未读 继续免费阅读

下载本文档

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

文档简介

1、模块模块的的测试测试 如何把被测模块的输出变化记录到数据库文件中?如何把被测模块的输出变化记录到数据库文件中? (文件格式为VCD,大多数的波形显示工具都能读取该格式) 可用以下七个系统任务:可用以下七个系统任务: 1)$dumpfile(“file.dump”); /打开记录数据变化的数据文件 2)$dumpvars(); /选择需要记录的变量 3)$dumpflush; /把记录在数据文件中的资料转送到硬盘保存 4)$dumpoff; /停止记录数据变化 5)$dumpon; /重新开始记录数据变化 6)$dumplimit(); /规定数据文件的大小(字节) 7)$dumpall; /记

2、录所有指定信号的变化值到数据文件中 模块模块的的测试测试 如何把被测模块的响应变化记录到数据库文件中?如何把被测模块的响应变化记录到数据库文件中? 举例说明:举例说明: $ $dumpvarsdumpvars; ; /记录各层次模块中所有信号的变化 $ $dumpvars(1,top); dumpvars(1,top); /只记录模块top中所有信号的变化 $ $dumpvars(2,top.u1); dumpvars(2,top.u1); /记录top模块中实例u1和它以下一层子模块所有信号的变化 $ $dumpvars(0,top.u2,top.u1.u13.q); dumpvars(0,

3、top.u2,top.u1.u13.q); /记录top模块中实例u2和它本层所有信号的变化,还有top.u1.u13.q 信号的变化。 $ $dumpvars(3,top.u2,top.u1); dumpvars(3,top.u2,top.u1); /记录top模块中u2和u1所有信号的变化(包括其两层以下子模块的信号 变化)。 模块模块的的测试测试 如何把被测模块的响应变化记录到数据库文件中?如何把被测模块的响应变化记录到数据库文件中? 举例说明:举例说明: 下面的 Verilog 代码段可以代替测试文件中的系统任 务$monitor initialinitial begin begin

4、$ $dumpfile(“vlog.dumpdumpfile(“vlog.dump”);); $ $dumpvars(0,top); dumpvars(0,top); end end 语法详细讲解 编译引导语句编译引导语句 使用使用 uselib 的语法:的语法: uselib 器件库1的地点 器件库2的地点 。 上面的器件库地点可用以下两种方法表示: 1) file = 库文件名的路径 2) dir = 库目录名的路径 libext = .文件扩展 例如例如: uselib dir =/lib/FAST_lib/ uselib dir =/lib/TTL_lib/ libext=.v fil

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

6、state_reg; end force 和 release 用于寄存器类型和网络连接类型(例如:门级扫 描寄存器的输出)的强制赋值,强制改写其它地方的赋值。 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所赋

7、的值, 语法详细讲解 强制激励 语法详细讲解 字符串字符串 语法详细讲解 强制激励强制激励 语法详细讲解 强制激励 当执行release后,则信号的值为assign所赋 的值。 如果用force对同一个信号赋了几次值,再执行release,则 所有赋的值均不再存在。 可以对信号的某(确定)位、某些(确定)位或拼接的 信号,使用force和release赋值;但不能对信号的可变位使 用force和release 来赋值。 不能对寄存器类型的信号某位或某些位使用 assign 和 deassign 来赋值。 语法详细讲解 强制激励强制激励 语法详细讲解 建立时钟 虽然有时在设计中会包含时钟,但时钟

8、通常用在测试模块中。下面 三个例子分别说明如何在门级和行为级建立不同波形的时钟模型。 例例1 1 简单的对称方波时钟简单的对称方波时钟: 语法详细讲解 建立时钟建立时钟 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 注:在有些仿真器中,如果设计所用的时钟是由与其相同抽象级别的时钟 模型产生的,则仿真器的性能就能得到提高。 例例22简单的

9、带延迟的对称方波时钟:简单的带延迟的对称方波时钟: 语法详细讲解 建立时钟 reg clk; initial begin clk=0; #(period) forever # ( p e r i o d / 2 ) clk=!clk end reg go; wire clk; nand #(period/2) ul (clk,clk,go); initial begin go=0; #(period) go=1; end 注:这两个时钟模型有些不同,行为描述的模型延迟期间一直是低电平, 而门级描述的模型开始延迟有半个周期是不确定的。 语法详细讲解 建立时钟 例例3. 3. 带延迟、头一个脉冲不

10、规则的、占空比不为带延迟、头一个脉冲不规则的、占空比不为1 1的时钟:的时钟: 语法详细讲解 建立时钟 reg clk; initial begin #(period+1) clk=1; #(period/2-1) forever begin #(period/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 注:这两个时钟模

11、型也有些不同,行为描述的模 型一开始就有确定的电平,而门级描述的模型有 延迟, 开始时电平是不确定的。 语法详细讲解 怎样使用任务 举例说明如何使用任务:举例说明如何使用任务: module bus_ctrl_tb; reg 7:0 data; reg data_valid, data_rd; cpu ul(data_valid,data,data_rd); initial begin cpu_driver (8b0000_0000); cpu_driver (8b1010_1010); cpu_driver (8b0101_0101); end 语法详细讲解 怎样使用任务怎样使用任务 语法详

12、细讲解 怎样使用任务 task cpu_data; input 7:0 data_in; output 7:0 data; begin #30 valid=1; wait(rd=1); #20 data=data_in; wait(rd=0); #20 data=8hzz; #30 valid=0; end endtask endmodule 语法详细讲解 怎样使用任务怎样使用任务 语法详细讲解 怎样使用任务 在测试模块中使用任务可以提高程序代码的效率,可以用 任务把多次重复的操作包装起来。 语法详细讲解 怎样使用任务怎样使用任务 waitwaitwaitwaitdata1 data2data

13、3 data4 cpu_data clk valid rd read_cpu_state 语法详细讲解 存储建模 目标目标 学会如何用Verilog对存储器建模。 学会如何用Verilog中对双向(即输入/输出)端口, (inout)建模。 语法详细讲解 第十五部分第十五部分 存储器建模存储器建模 存储器建模必须注意以下两个方面的问题:存储器建模必须注意以下两个方面的问题: 声明存储器容量的大小。 明确对存储器访问操作的权限。 例如:指出可以对存储器做以下哪几种操作: 1)只读 2)读写 3)同步读写 4)多次读,同时进行一次写 5)多次同步读写,同时提供一些方法保证一致性 语法详细讲解 存储

14、器建模存储器建模 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; endmodule 语法详细讲解 简单简单 ROM ROM 建模建模 my_rom_dat

15、amy_rom_data 0000 0101 1100 0011 1101 0010 0011 1111 1000 1001 1000 0001 1101 1010 0001 1101 ROM ROM的数据存储的数据存储 在另外的一个独在另外的一个独 立的文件中立的文件中 语法详细讲解 简单简单ROMROM建模建模 上页所示的上页所示的ROMROM模型说明:模型说明: 如何在Verilog中用二维的寄存器组来定义存储器。 ROM中的数据保存在一个独立的文件中,如上页的右边 的虚线方框所示。 这是一种保存ROM数据的通用的方法,它可以使数据和 ROM模型分开。 语法详细讲解 简单简单RAMRAM

16、建模建模 timescale 1ns/1ns module mymem(data,addr,read,write); inout 3:0 data; inout 3:0 addr; input read, write; reg 3:0 memory 0:15; /4 bits, 16 words /从存储器读出到总线上 assign data=read? memoryaddr:4bz; /从总线写入存储器 always (posedge write) memoryaddr=data; endmodule 语法详细讲解 简单简单RAMRAM建模建模 RAMRAM模型比模型比ROMROM模型稍微复

17、杂:模型稍微复杂: 它必须具有读写能力; 进行读写时通常使用相同的数据总线; 需要新技术来处理双向总线; 当读信号无效时,RAM模型与总线脱离,如果此时写 信号也无效,总线无驱动源,则总线进入高阻状态, 这就避免了RAM中的读写竞争。 上页的 RAM 模块是可综合的,但综合出来是一大堆寄存器 ,占比较大的面积,经济上不太合算。 例:例: module scalable_ROM (mem_word, address); parameter addr_bits=8; /size of address bus parameter wordsize=8; /width of a word parame

18、ter words=(1addr_bits); /size of mem output wordsize:1 mem_word; /word of memory 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 语法详细讲解 存储量可变的只读存储器建模存储量可变的只读存储器建模 语法详细讲解 存储量可变的只读存储器建模存储

19、量可变的只读存储器建模 上述的例子演示了怎样通过设置字长和地址位数来编 写 只读存储器的行为模块。 注意 ! 在上例中,存储字的范围从0开始的,而不是 从1开始,这是因为存储单元是直接通过地址线寻址 定位的。 同样地,也可以用下面的方法来定义存储器和寻址: reg wordsize:1 mem 1:words; /存储器地址 从1 开始 /地址一个一个地增加直到包含了每个地址对应的存储器 wire wordsize:1 mem_word = memaddress+1; 可以在初始化块中用一个循环或系统任务把初始数据存入存 储器的每个单元。 使用循环把值赋给存储器数组。 for(i=0;imem

20、size;i=i+i) / initialize memory memai=wordsize1b1; 调用$readmem系统任务。 /从文件 mem_file.txt 中, 把初始数据存入存储器(mem)的每个单元 $readmemb(“mem_file.txt”,mem); 注意:注意:上面两项必须写 在initial 块中,加载这些初始化数据不需要 时间。 语法详细讲解 存储器的加载存储器的加载 语法详细讲解 怎样使用双向口怎样使用双向口 使用使用inout关键字声明端口为双向口。关键字声明端口为双向口。 inout 7:0 databus; 使用双向口必需遵循下面的规则:使用双向口必需

21、遵循下面的规则: inout口只能声明为网络连接类型, 不允许把它声明为 寄存器类型。(所以仿真器能确定多个驱动源的最终 值。) 在设计中,每次只能从一个方向来驱动inout口口。 例如:当使用总线读RAM中的数据时,如果同时又向 RAM模型的双向数据总线写数据,就会产生逻辑竞争 ,导致总线数据无法确定。所以必须为inout口设计控 制逻辑,只有这样才能保证正确的操作。 语法详细讲解 怎样使用双向口怎样使用双向口 注意注意 : 声明一个inout口,可以用来输入或输出数据。inout口默认为网络 连接类型。不允许在过程块(initial 或always块)中对网络连接类 型的数据进行过程赋值;

22、但可以在过程块外把一个寄存器数据类 型通过连续赋值语句赋给它(inout口),或者把它与用户定义的 源语(UDP)相连。 必须为inout口设计控制逻辑,用来保证正确的操作。当把inout口 作为输入口时,必须通过控制逻辑禁止输出到inout口。 使用使用Verilog中的基本元件(中的基本元件(bufif1)为双向口建模:为双向口建模: 语法详细讲解 双向口建模双向口建模 b2b2 b1b1 en_a_ben_a_b en_b_aen_b_a bus_abus_abus_bbus_b module bus_xcvr (bus_a,bus_b,en_a_b,en_b_a); inout bus

23、_a,bus_b; input en_a_b,en_b_a; bufifl b1(bus_b,bus_a,en_a_b); bufifl b2(bus_a,bus_b,en_b_a); /结构模块逻辑 endmodule 当当en_a_b=1en_a_b=1时,元器时,元器 件件b1b1激活,激活,bus_abus_a的值传的值传 到到bus_bbus_b上上 当当en_b_a=1en_b_a=1时,元器时,元器 件件b1b1激活,激活,bus_bbus_b的值传的值传 到到bus_abus_a上上 语法详细讲解 双向口建模双向口建模 注意注意 : 在上页的例子中,使用在上页的例子中,使用en

24、_a_ben_a_b和和en_b_a en_b_a 来控制元器件来控制元器件 bufiflbufifl, ,如果控制信号同时有效,则结果无法确定。如果控制信号同时有效,则结果无法确定。 所以必须把控制信号所以必须把控制信号 en_a_b en_a_b 和和 en_b_a en_b_a 在时间上分在时间上分 开。开。 使用连续赋值使用连续赋值为双向口建模:为双向口建模: en_a_ben_a_b en_b_aen_b_a bus_abus_abus_bbus_b module bus_xcvr (bus_a,bus_b,en_a_b,en_b_a); inout bus_a,bus_b; inp

25、ut en_a_b,en_b_a; assign bus_b=en_a_b? bus_a:bz; assign bus_a=en_b_a? bus_b:bz; /结构模块逻辑 endmodule 当当en_a_b=1en_a_b=1时,时,bus_abus_a的的 值传到值传到bus_bbus_b上上 当当en_b_a=1en_b_a=1时,时,bus_bbus_b的的 值传到值传到bus_abus_a上上 语法详细讲解 双向口建模双向口建模 b2b2 b1b1 注意注意 : 在在assignassign语句中,通过语句中,通过en_a_ben_a_b和和en_b_aen_b_a控制控制bus

26、_abus_a与与 bus_bbus_b之间的数据交换。之间的数据交换。 如果控制信号同时有效,则结果不能确定如果控制信号同时有效,则结果不能确定。所以必须所以必须 把控制信号把控制信号 en_a_b en_a_b 和和 en_b_a en_b_a 在时间上分开。在时间上分开。 语法详细讲解 双向口建模双向口建模 存储器的端口建模:存储器的端口建模: 语法详细讲解 双向口建模双向口建模 module ram_cell(databus,rd.wr); inout databus; input rd,wr; reg datareg; assign databus=rd? datareg:bz; a

27、lways (negedge wr) datareg=databus; endmodule 当当rdrd等于等于1 1时时dataregdatareg的的 值被赋给值被赋给databusdatabus 当当wrwr的下降沿到达时,的下降沿到达时, databusdatabus的值被写入的值被写入 dataregdatareg 测试模块测试模块RAMRAM单元单元 数据总线数据总线 数据数据 寄存寄存 器器 rdrd wrwr 注意注意 : 上页中存储单元在上页中存储单元在wrwr的下降沿到达时存入数据。的下降沿到达时存入数据。 上页模块在上页模块在 wrwr处于高电平时,通过数据总线写入数处于

28、高电平时,通过数据总线写入数 据,但必须保证据,但必须保证wrwr的高电平维持时间长于数据的写的高电平维持时间长于数据的写 入时间。入时间。 在在rdrd处于高电平时,上述存储单元通过数据总线处于高电平时,上述存储单元通过数据总线 读出数据。由于此模型为单口存储模型,因此读出数据。由于此模型为单口存储模型,因此wrwr变变 低电平时,低电平时,rdrd不能同时为高电平,否则就无法确定不能同时为高电平,否则就无法确定 存储器的读出存储器的读出/ /写入的结果。写入的结果。 语法详细讲解 双向口建模双向口建模 目标目标: 学会怎样定义或调用任务和函数。学会怎样定义或调用任务和函数。 学会怎样使用命

29、名块。学会怎样使用命名块。 学会怎样禁止命名块和任务。学会怎样禁止命名块和任务。 理解有限状态机的作用,学会如何显式理解有限状态机的作用,学会如何显式 地为有限状态机建模。地为有限状态机建模。 语法详细讲解 第十六部分第十六部分 VerilogVerilog中的高级结构中的高级结构 通过把代码分成小的模块或者使用任务和函数,可把一项任务分 成许多较小的、易于管理的部分,从而提高代码的可读性、可 维护性和可重用性。 任务 一般用于编写测试模块,或者行为描述的模块。 其中可以包含时间控制(如:# delays, , wait); 也可以包含input, output 、inout 端口定义和参数;

30、 也可以调用其他的任务或函数 函数 一般用于计算,或者用来代替组合逻辑。 不能包含任何延迟;函数在零时间执行。 函数只有input变量,虽然没有output变量, 但可以通过函数名返回一个值。 可以调用其他的函数,但不可以调用任务 语法详细讲解 VerilogVerilog中的高级结构中的高级结构 注意: 只能调用本模块内的任务和函数。 在任务和函数中不能声明网络连接类型的变量。 所有的输入和输出变量实际上都是本地寄存器 。 只有当任务或函数调用并执行完后,才能有返回值。 举例说明: 若任务或函数中包含一个forever循环时,永远无法执 行完,就不可能有返回值。 语法详细讲解 Verilog

31、Verilog中的高级结构中的高级结构 语法详细讲解 VerilogVerilog 任务任务 下面模块中的任务含有定时控制和一个输入,并且 引用了一个本模块的变量,但是没有输出,也没有双 向总线和内部变量,不显示任何内容。 用于定时控制的信号,例如 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; rep

32、eat(number_of_edges) (negedge clk); endtask initial begin clk=0; a=1; b=1; neg_clocks(3); /任务调用 a=0; neg_clocks(5); b=0; end endmodule 语法详细讲解 VerilogVerilog 任务任务 要点:要点: 任务调用是通过在Verilog模块中写入任务名来实现的。 任务中可以包含inputinput, outputoutput和inoutinout端口变量的声明。 传递给任务的变量与任务I/O端口变量的声明次序相同。虽然传递给任 务的变量名可以和任务内声明的I/O端

33、口变量名相同,但是为了使任务 成为一个独立的可共用的任务块,建议不要使用与任务内声明的I/O端 口变量名相同的变量名,最好给传递到任务的变量起新的不同的名字。 在任务中可以使用时间控制。 任务使Verilog有更广阔的适用范围。 关键字disable可以用来禁止任务的执行。 语法详细讲解 VerilogVerilog 任务任务 注意注意 : 不要在程序的不同部分同时调用同一个任务。这是因 为任务只有一组本地变量,同一时刻调用两次相同的 任务将会导致错误。这种情况常发生在使用定时控制 的任务中。 在任务或函数中,引用父模块中声明的变量时要特别 注意(即注意变量的层次命名规则)。若想在其它模 块中

34、调用任务或函数,该任务和函数中所使用的变量 必须全都包含在输入/输出口列表中。 语法详细讲解 VerilogVerilog 任务任务 下面模块中的任务只含有一个双向总线(inout)端口和一个内部变量 ,没有其它输入端口、输出端口和定时控制,没有引用模块变量,不 显示任何内容。 在任务调用时,任务的输入变量(端口)在任务内部被当作寄存器类 型变量处理。 parameter MAX_BITS=8; reg MAX_BITS:1 D; task reverse_bits; inout 7:0 data; /双向总线端口被当作寄存器类型!双向总线端口被当作寄存器类型! integer K; for

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

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

37、 7:0 out; reg 7: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) else f_or_and=0; endfunction endmodule 语法详细讲解 VerilogVerilog 函数函数 虽然函数不能包含定时控制,但是可以在包含定时控制的过程 块中调用函数。 在模块中,使用名为f_or_and的函数时,是把它作为名为

38、f_or_and 的寄存器类型变量来处理的。 要点要点 函数定义不能包含任何定时控制语句。 函数必须至少有一个输入,但绝不能含有任何输出和总线口; 一个函数只能返回一个值,该值的变量名与函数同名,数据类 型默认为reg类型。 传递给函数的变量顺序与函数输入口声明的顺序相同。 函数定义必须包含在模块定义之内。 函数不能调用任务,但任务可以调用函数。 函数使Verilog有更广阔的适用范围。 语法详细讲解 VerilogVerilog 函数函数 虽然函数只能返回一个值,但是它的返回值可以直接赋给一个 由多个子信号拼接构成的信号变量, 使其实际等效于产生了多 个输出。 o1, o2, o3, o4=

39、f_or_and(a, b, c, d, e); 语法详细讲解 VerilogVerilog 函数函数 在函数定义时,如果在函数名前面定义了位宽,该函数就可以返回由多位构成的矢 量。如果定义函数的语句比较多时,可以用 begin 和end 把它们组合起来。 在函数内,无论以函数名命名的变量被赋了多少次值,函数只有一个返回值。 下例中的函数,声明了一个内部整型变量。举例说明如下: module foo; input 7:0 loo; /也可以用连续赋值语句调用函数 wire 7:0 goo = zero_count (loo); function 3:0 zero_count; input 7:

40、0 in_bus; integer I; begin zero_count = 0; for (I=0; I8; I= I+1) if (!in_busI) zero_count = zero_count +1; end endfunction endmodule 语法详细讲解 VerilogVerilog 函数函数 若把函数定义为整型、实型或时间类型, 就可以返回相应类型 的数据。我们可以在任何类型的表达式中调用函数。 module checksub(neg,in_a,in_b); output neg; input a, b; reg neg; function integer subtr

41、; input 7:0 in_a, in_b; subtr = in_a in_b; /运算结果可以为负数 endfunction always (a or b) begin if ( subtr (a,b) 0) neg = 1; else neg = 0; end endmodule 语法详细讲解 VerilogVerilog 函数函数 函数类型、端口和行为定义时也可以使用参数, 这样就可以构 成参数化函数使其返回的数据类型、输入端口的位宽等很容易 做修改。所以参数化函数就有更广泛的适用范围。 . parameter MAX_BITS =8; reg MAX_BITS:1 D; funct

42、ion MAX_BIT:1 reverse_bits; input 7:0 data; for(K=0; K MAX_BITS; K=K+1) reverse_bits MAX_BITS (K+1) = data K; endfunction always (posedge clk) begin . D= reverse_bits(D); . end 语法详细讲解 VerilogVerilog 函数函数 语法详细讲解 命名块命名块 可以通过在关键字begin或fork后加上:块名来给块命名。 module named_blk; begin :seq_blk end fork : par_blk

43、 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 : arith_block /*命

44、名名为arith_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 注意:注意: disabledisable语句用来终止命名块或任务的执行。这是指在尚未

45、执行 该命名块或任务任何一条语句前,就从该命名块/任务执行中返 回。 语法:语法: disable 块名 或 disable 任务名 禁止执行命名块或任务后,所有在事件队列中由该命名块/任务 安排的事件都将被删除。 一般 情况下disable语句是不可综合的。 在上页的例子中,只禁止命名块也可以得到预期的结果:命名块 中所有的事件,包括任务和函数的执行都将被取消。 语法详细讲解 禁止命名块和任务禁止命名块和任务 语法详细讲解 有限状态机(有限状态机(FSM)FSM) 隐式隐式FSM: 不需要状态寄存器 仿真更加有效 只能很好地处理线性 的状态改变 大部分综合工具不支 持隐式FSM state

46、1state 1 state 2state 2 state 3state 3 state 4state 4 语法详细讲解 编译引导语句编译引导语句 显式显式FSM: 结构比较复杂 可以很方便的用来处理默认 状态 能够处理复杂的状态改变 所有的综合工具均支持显式 FSM 的综合 语法详细讲解 有限状态机(有限状态机(FSM)FSM) state Astate A state B1state B1state B2state B2 state Cstate C state Dstate D 注意:注意: 在隐式状态机中,只要发生在一个时钟周期内写数据,在另一 个时钟周期内读数据的情况,都会生成寄存器

47、。 任何状态机都必须有复位控制信号,状态的改变必需只与某单 一时钟信号沿同步。 一般情况下,如果状态改变比较简单,又定义得比较好,而且 综合工具支持隐式状态机的综合,就可以使用隐式状态机。如 果状态改变比较复杂,最好使用显式状态机,这样效果更好。 隐式状态机属于行为级,不属于RTL级。代码中主要包含循环 语句、嵌入的定时控制,有时也含有命名事件、wait 和 disable 语句。一般情况下,常用的综合工具不支持隐式状态机的综合 。 语法详细讲解 有限状态机(有限状态机(FSMsFSMs) ) 语法详细讲解 显式有限状态机显式有限状态机 module exp(out, datain, clk,

48、 rst); input clk, rst, datain; output out; reg out; reg state; always (posedge clk or posedge rst) if(rst) state, out=2b00; else case(state) 1b0: begin out=1b0; if(!datain) state=1b0; else state=1b1; end 1b1 begin 状态变量状态变量 语法详细讲解 显式有限状态机显式有限状态机 casecase语句语句 0 0 1 1 dataindatain = 0 = 0 dataindatain

49、= 1 = 1 out=datain; state=1b0; end default: state, out=2b00; endcase endmodule 注: 在过程块中可以使用一个时钟沿和 case 语句来描述一个显式状 态机。 必须指定一个状态变量,来记录状态机的状态。 要改变当前的状态,必须改变状态变量的值, 其改变要与时钟 沿同步。 写得比较好的状态机常为不应产生的条件规定一个默认动作。 语法详细讲解 显式有限状态机显式有限状态机 转到下一个状态转到下一个状态 默认状态指针默认状态指针 0 01 11 10 01 1 识别1111序列 clkclkrstrst outout beg

50、in: seq_block out=1b0; if(!datain) /状态一:输出零 disable seq_block; (posedge clk) /状态二:输出第二位 out=datain; end endmodule 语法详细讲解 隐式有限状态机隐式有限状态机 0 01 11 10 01 1 识别1111序列 clkclkrstrst outout 注意:注意: 在过程块中可以使用多个时钟沿(即每次状态改变都用一个新的时钟 沿)、条件语句、循环语句、disable语句来描述隐式FSM。隐式FSM往 往是不可综合的。 隐式FSM不必指定状态变量。 当下一个激活时钟沿到达时,状态就有可能

51、发生改变。下一个状态是否 改变,将由条件语句决定;除非用强制性语句使状态重复(例如:用循 环语句或用disable语句来强制改变状态), 在隐式状态机中,很难规定一个默认动作。 语法详细讲解 隐式有限状态机隐式有限状态机 目标目标 学会怎样使用用户定义的原语来创建逻辑。学会怎样使用用户定义的原语来创建逻辑。 用户定义的源语元件用户定义的源语元件 (UDP) 其行为与其行为与 Verilog 语法中语法中 本来就存在的本来就存在的primitive(源语元件)相似,它用一个表源语元件)相似,它用一个表 格来定义它的逻辑功能。格来定义它的逻辑功能。 语法详细讲解 第十七部分第十七部分 用户定义的原

52、语用户定义的原语 在 Verilog 结构建模时,可以使用: 二十多个门级源语元件(primitives)。 用户定义的源语元件(UDP)。 UDP 可用于ASIC 库中的基本元件(cell)设计,以及小规模芯片和 中规模芯片的设计。 使用 UDP可以在现有的Verilog 语言支持的源语元件的基础上编写 新的源语元件。 UDP 是一个独立元件, 不能用实例调用的方法调用其他的模块。 UDP 既可以用来表示时序逻辑元件,也可以表示组合逻辑元件。 UDP 的行为是使用真值表来描述的 。 调用 UDP 的方式与调用Verilog语言提供的源语元件的方式相同。 语法详细讲解 什么是什么是UDPUDP

53、? 注意: UDP 是一种紧凑的表示简单逻辑关系部件的方法。 在Verilog语言提供的几种基本源语元件中,若在输入 中包含不确定值x,则在输出时可能出现不确定值 x; 而在 UDP 中则不允许出现此种情况。 由几个原语元件组成的逻辑可以用一个UDP表示。在 仿真时使用这样的UDP来代替分散的原语元件可以节 省计算资源,加快仿真速度。一般的仿真器处理行为 模型表示的逻辑所需时间比处理用门级语句表示的相 同逻辑所需时间少;而硬件仿真器正好相反。 语法详细讲解 什么是什么是UDPUDP? UDP 只能有一个输出端,而且必须是端口说明列表的 第一项。 UDP 可以有多个输入端,最多允许有 10 个。

54、 UDP 所有端口变量必须是标量,不允许使用双向端口。 UDP 不支持Z(高阻)逻辑值。 在仿真的开始时刻,可以使用 initial 语句把UDP 的输 出初始化为一个已知值。 UDP 不支持综合,即不能通过综合把它转变为门级结 构逻辑。 语法详细讲解 UDPUDP的特点的特点 注: UDP 只能有一个输出。如果逻辑功能要求有多个输出 端时,则需要把其它的原语元件连接到 UDP的 输出, 或同时使用多个 UDP,保证其最终输出只有一个。 UDP 输入端最多可以有 10 个,但是当输入端的个数 多于 5 个时,仿真时需要的内存个数将呈现近似指数 的增加。下表列出了当输入数目不同时,在仿真过程 中

55、,对每个输入信号,计算机中所需要开销的内存数 目。 语法详细讲解 UDPUDP的特点的特点 语法详细讲解 UDPUDP的特点的特点 输入端口的个数输入端口的个数所需内存的字节数所需内存的字节数 1-51 65 717 856 9187 10623 组合逻辑示例:组合逻辑示例: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

56、1 x : 1; endtable endprimitive 原语名原语名 输出端口必须为输出端口必须为 第一个端口第一个端口 注:注: 在模块外定义 UDP 。 如果在表中没有规定输入组合,将输出不确定逻辑值 (x)。 表的列中元素的顺序应与端口列表中的一致。 表中的 ?的意义是:重复的输入 0,1或 任意不确定逻辑值(x)。 表中开始两行表示:当 s等于 1 时,不管 b 逻辑值如何变化,输出 o 将与 输入 a 保持一致。 表中的下两行表示:当 s 等于 0 时,不管 a逻辑值如何变化,输出 o 将与 输入 b 保持一致。 表中 的最后两行使此器件的描述更加的全面、准确。它们表示:当输入

57、 a 和 b 的逻辑值相同时,如果 sel 逻辑值不确定,则输出 o 的值 将与输入 a 和 b 的值相同。这种行为不能使用 Verilog 语言提供的基本源语元件进行 建模。UDP 将 x 作为实际的未知值,而不是 Verilog 语言逻辑值来进行处 理,因此使其比Verilog语言提供的基本源语元件更加准确。 语法详细讲解 举例说明举例说明 可以只使用两个 UDP 来描述全加器的逻辑功能。 / 全加器进位实现部分 primitive U_ADDR2_C (CO, A, B, CI); output CO; input A, B, CI, table / A B CI : CO 1 1 ?

58、: 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; 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

59、; endtable endprimitive 语法详细讲解 组合逻辑示例:全加器组合逻辑示例:全加器 若使用 UDP 设计全加器,仅需要两个 UDP; 而使用 Verilog 原语 元件,则需要 5 个Verilog语言提供的基本原语元件。 当设计需要使用大量全加器时,采用UDP来表示全加器,将大大 减少内存的需要。 事件的数目将大大降低。 ?表示逻辑值可以为 0,1或 x。 语法详细讲解 组合逻辑示例:全加器组合逻辑示例:全加器 primitive latch(q, clock, data); output q; reg q; input clock, data; initial q=1b

60、1; table / clock data current next / state state 0 1 : ? 1; 0 0 : ? 0; 1 ? : : -; endtable endprimitive 语法详细讲解 电平敏感的时序逻辑示例:锁存器电平敏感的时序逻辑示例:锁存器 注意此寄存器的用法,注意此寄存器的用法, 此寄存器用来存储。此寄存器用来存储。 输出初始化为输出初始化为 11b1.b1. ? ? 表示无须考虑输入表示无须考虑输入 和当前状态的值和当前状态的值 注: 锁存器的动作行为如下: 当时钟信号为 0时,输入数据的值直接传给输出。 当时钟信号为1时,输出保持当前状态不变。

温馨提示

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

评论

0/150

提交评论