3-Verilog HDL详细语法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
特殊符号 “#”
特殊符号 “#” 常用来表示延迟:
在过程赋值语句时表示延迟。 例:initial begin #10 rst=1; #50 rst=0; end 在门级实例引用时表示延迟。 例:not #1 not1(nsel, sel); and #2 and2(a1, a, nsel); 在模块实例引用时表示参数传递
net
输出/入口
net inout
module DUT(Y, A, B_); output Y; input A,B:
net
wire Y, A, B;
and (Y, A, B); endmodule
选择数据类型时常犯的错误
在过程块中对变量赋值时,忘了把它定义为寄存器 类型(reg)或已把它定义为连接类型了(wire) 把实例的输出连接出去时,把它定义为寄存器类型 了 把模块的输入信号定义为寄存器类型了。
端口与外部信号的连接
在调用模块时,可以用顺序连接和按名连接把模块 定义的端口与外部信号连接起来
顺序连接:需要连接的信号需要与模块声明的端口列表一致; 按名连接:端口和外部信号按名字连接在一起.
module D_FF (d, clk, clr, q, qb); .... endmodule module REG4( d, clk, clr, q, qb); output [3: 0] q, qb; input [3: 0] d; input clk, clr; D_FF d0 (d[ 0], clk, clr, q[ 0], qb[ 0]); D_FF d1 (d[ 1], clk, clr, q[ 1], qb[ 1]); D_FF d2 (d[ 2], clk, clr, q[ 2], qb[ 2]); D_FF d3 (d[ 3], clk, clr, q[ 3], qb[ 3]); endmodule
-------------------------------------------------------
例:
initial $monitor($time,”a=%b, b=%h”, a, b);
//每当a 或b值变化时该系统任务都显示当前的仿真时刻并分别 用二进制和十六进制显示信号a和 b的值
第三部分 Verilog HDL详细语法
主要内容:
Verilog与C的主要不同点 模块实例化要点 如何选择正确的数据类型 Verilog HDL模块的测试 Verilog测试模块的编写 存储器建模 Verilog中的高级结构 用户定义的原语
3.1 Verilog与C的主要不同点
//1.23 ps中共有12个STU(100fs)
编译引导语句
时间单位 :
fs (呼秒)femptoseconds: ps (皮秒) picoseconds: ns (纳秒) nonoseconds: us (微秒) microseconds: ms (毫秒) milliseconds: s ( 秒) seconds: 1.0E-15 1.0E-12 1.0E-9 1.0E-6 1.0E-3 1.0 秒 秒 秒 秒 秒 秒
编译引导语句
使用 `uselib 的语法:
`uselib 器件库1的地点 器件库2的地点 。。。
上面的器件库地点可用以下两种方法表示: 1) file = 库文件名的路径 2) dir = 库目录名的路径 libext = .文件扩展 例如:
`uselib dir =/lib/FAST_lib/ `uselib dir =/lib/TTL_lib/ libext=.v file = /libs/TTL_U/udp.lib
模块的测试(续)
被测模块
激励和控 制信号
输出响应 和验证
模块的测试(续)
测试模块常见的形式:
module t; reg …; //被测模块输入/输出变量类型定义 wire…; //被测模块输入/输出变量类型定义 initial begin …; …; …; end … …//产生测试信号 always #delay begin …; end … …//产生测试信号 testedmd m(.in1(ina), .in2(inb), .out1(outa), .out2(outb) ); //被测模块的实例引用 initial begin ….; ….; …. endmodule end //记录输出和响应
编译引导语句
`timescale 用于说明程序中的时间单位和仿真精度 举例说明: `timescale 1ns/100ps `timescale 语句必须放在模块边界前面 举例说明: `timescale 1ns/100ps
module MUX2_1(out,a,b,sel); …… not #1 not1(nsel, sel); and #2 and1(a1, a, nsel); …… endmodule
3.3 如何选择正确的数据类型
输入口(input)可以由寄存器或网络连接驱动,但它本身只能驱动 网络连接。 输出口 (output)可以由寄存器或网络连接驱动,但它本身只能驱动 网络连接。 输入/输出口(inout)只可以由网络连接驱动,但它本身只能驱动网络 连接。 如果信号变量是在过程块 (initial块 或 always块)中被赋值的,必 须把它声明为寄存器类型变量
尽可能地使精度与时间单位接近,只要满足设计的 实际需要就行。 举例说明:在上例中所有的时间单位都是1ns的整数倍
编译引导语句
仿真步长即仿真单位(STU) 是所有参加仿真模块中由`timescale 指定 的精度中最高(即时间最短)的那个决定的: (STU=100fs) 举例: `timescale 1ns/10ps module M1(….); not #1.23 not1(nsel, sel); //1.23 ns中共有12300个STU(100fs) endmodule `timescale 100ns/1ns module M2(….); not #1.23 not1(nsel, sel); //123 ns中共有1230000个STU(100fs) endmodule `timescale 1ps/100fs module M3(….); not #1.23 not1(nsel, sel); endmodule
Verilog 有许多语法规则与 C 语言一致。
但与 C 语言有根本的区别: 并行性 块的含义: initial 块 和 always块 两种赋值语句: 阻塞 赋值 “=”
非阻塞赋值
“ <= ”
系统任务和函数
$<标识符> ‘$’ 符号表示 Verilog 的系统任务和函数 常用的系统任务和函数有下面几种: 1) $time //找到当前的仿真时间 2) $display, $monitor //显示和监视信号值的变化 3) $stop //暂停仿真 4) $finish //结束仿真
模块的测试(续)
如何把被测模块的输出变化记录到数据库文件中?
(文件格式为VCD,大多数的波形显示工具都能读取该格式)
可用以下七个系统任务:
1) 2) 3) 4) 5) 6) 7)
$dumpfile(“file.dump”); //打开记录数据变化的数据文件 $dumpvars(); //选择需要记录的变量 $dumpflush; //把记录在数据文件中的资料转送到硬盘保存 $dumpoff; //停止记录数据变化 $dumpon; //重新开始记录数据变化 $dumplimit(<file_size>); //规定数据文件的大小(字节) $dumpall; //记录所有指定信号的变化值到数据文件中
Hale Waihona Puke Baidu
这是经常犯的三个错误!!!
3.4 模块的测试
如何检查模块功能是否正确?
需要有测试激励信号输入到被测模块 需要记录被测模块的输出信号 需要把用功能和行为描述的Verilog模块 转换为门级电路互连的电路结构(综合)。 需要对已经转换为门级电路结构的逻辑 进行测试(门级电路仿真)。 需要对布局布线后的电路结构进行测试。 (布局布线后仿真)。
编译引导语句
编译引导语句用主键盘左上角小写键 “ ` ” 起头 用于指导仿真编译器在编译时采取一些特殊处理 编译引导语句一直保持有效,直到被取消或重写 `resetall 编译引导语句把所有设置的编译引导恢复到 缺省状态 常用的编译引导有: a) `define b) `include c) `timescale d) `uselib e) `resetall ……..
3.2 模块实例化要点
可以将模块的实例通过端口连接起来构成一个大的系统或元件。 每个实例都有自己的名字。实例名是每个对象唯一的标记,通过
这个标记可以查看每个实例的内部。
实例中端口的次序与模块定义的次序相同。 模块实例化与调用程序不同。每个实例都是模块的一个完全的拷
贝,相互独立、并行。
举例说明数据类型的选择
module top; wire y; reg a, b; DUT u1(y,a,b); initial begin a = 0; b = 0; #10 a =1; …. end endmodule
模块DUT的边界
net/register
输入口
net
net/register
输出口
编译引导语句
使用`define 编译引导能提供简单的文本替代功能 `define <宏名> <宏文本> 在编译时会用宏文本来替代源代码中的宏名。 合理地使用`define可以提高程序的可读性
举例说明:
`define on 1’b1 `define off 1’b0 `define and_delay #3 在程序中可以用有含义的文字来表示没有意思的数码提高了程序 的可读性,在程序中可以用 `on, `off, `and_delay 分别表 示 1,0,和 #3 。
模块的测试(续)
如何观察被测模块的响应: 在initial 块中,用系统任务$time 和 $monitor $time 返回当前的仿真时刻 $monitor 只要在其变量列表中有某一个或某几个变 量值发生变化,便在仿真单位时间结束时显示其变 量列表中所有变量的值。
例: initial begin $monitor ($time, “out=%b a=%b sel=%b”, out, a, sel); end
编译引导语句
使用`include 编译引导,在编译时能把其指定的整 个文件包括进来一起处理
举例说明:
`include “global.v” `include “parts/counter.v” `include “../../library/mux.v”
合理地使用`include 可以使程序简洁、清晰、条理清 楚、易于查错。
当设计大规模系统时,端口太多,记住端口顺序 不大可能,可以采用按名连接方法。
D_FF d0 (.d(d[0]), .clk(clk), .clr(clr), .q(q[0]), .qb(qb[0]));
不需要连接的端口直接忽略掉即可
D_FF d0 (.d(d[0]), .clk(clk), .clr(clr), .q(q[0]));
模块的测试(续)
测试模块中常用的过程块:
initial always 所有的过程块都 在0时刻同时启 动;它们是并行 的,在模块中不 分前后。 initial块 只 执行一次。 always块 只 要符合触发条件 可以循环执行。
模块的测试(续)
如何描述激励信号: module t; reg a, b, sel; wire out; //引用多路器实例 mux2_m (out, a, b, sel); //加入激励信号 initial begin a=0; b=1; sel=0; #10 b=0; #10 b=1; sel=1; #10 a=1; #10 $stop; end
编译引导语句
`uselib 编译引导语句:
用于定义仿真器到哪里去找库元件 如果该引导语句启动的话 ,它就一直有效 直到遇到另外一个`uselib的定义或`resetall语 句 比其他配置库搜索路径的命令选项作用大
如果仿真器在`uselib定义的地点找不到器件库,它 不会转向由编译命令行-v 和-y选项指定的器件库去 找。