一、编译指令特性:
1、编译指令是以反引号 ` 为前缀,ASCII为0x60,而不是单引号 ’ ,单引号的ASCII为0x27;
2、编译指令从处理到它开始就一直保持有效,除非后面被自己或者其他编译指令覆盖或者取消掉。
二、常用指令
1、宏定义指令`define, `undef
在编译阶段,`define 用于文本替换,类似于 C 语言中的#define。一旦 `define 指令被编译,其在整个编译过程中都会有效。一个文件定义后,另一个文件也可以直接使用,如果在两个文件里面的宏定义都使用了同一个名字,这个只是会报warning,不会报error,需要特别注意。
例如,在一个文件中定义
`define DATA_WIDTH 32
那么在另一个文件同样可以使用
`define S $stop;
//用`S来代替系统函数$stop; (包括分号)
`define WORD_DEF reg [31:0]
//可以用`WORD_DEF来声明32bit寄存器变量
`undef 用来取消之前的宏定义
`undef DATA_WIDTH
另外我试了下嵌套宏定义,最后发现没有报错。
`define DATA_WIDTH 32
`define WORD_DEF reg [DATA_WIDTH-1:0]
2、条件编译指令`ifdef, `ifndef, `elsif, `else, `endif
`ifdef 和 `endif 组成一次条件编译指令块,`elsif, `else 编译指令是可选的。当然,也可用 `ifndef 来设置条件编译,表示如果没有相关的宏定义,则执行相关语句。
例如,如果定义了 WIDTH_64,则使用第二种参数说明。如果没有定义,则使用第一种参数说明。
`ifndef WIDTH_64
parameter DATA_DW = 32 ;
`else
parameter DATA_DW = 64 ;
`endif
3、文件包含指令`include
使用 `include 可以在编译时将另一个 Verilog 文件内嵌到当前文件中,作用类似于 C 语言中的 #include 结构。该指令通常用于将全局或公用的头文件包含在设计文件里。文件路径既可以使用相对路径,也可以使用绝对路径。
`include "../../param.v"
`include "C:/Users/sf/Desktop/param.v"
`include "param.v"
需要注意的是路径用的是单左斜杠/
而不是单右斜杠\
,也可以使用双右斜杠\\
。
4、`timescale
`timescale用于指定后续模块的仿真时间单位和时间精度
使用格式为:
`timescale <time_unit>/<time_precision>
(1)time_unit是用于仿真时间和延迟值的测量单位,time_precision是用于仿真时间和延迟值的测量精度,当延迟值超出精度时,先舍入再使用;
(2)time_unit不能小于time_precision;
(3)time_unit和time_precision差别也不能太大,否则仿真速度会大受影响;
(4)可以使用$printtimescale显示模块的时间单位和时间精度;
(5)单位可以是s、ms、us、ns、ps、fs(秒、毫秒、微妙、纳秒、皮秒、飞秒)。
在编译过程中,`timescale 指令会影响后面所有模块中的时延值,直至遇到另一个 `timescale 指令或 `resetall 指令。由于在 Verilog 中没有默认的 `timescale,如果没有指定 `timescale,Verilog 模块就有会继承前面编译模块的 `timescale 参数。有可能导致设计出错。
如果一个设计中的多个模块都带有 `timescale 时,模拟器总是定位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小时延精度,时延单位并不受影响。
例如,
//子模块:
`timescale 1ns/100ps //时间单位为1ns,精度为100ps
//顶层模块:
`timescale 10ns/1ns //时间单位为10ns,精度为1ns
此例中,仿真顶层模块时,时延精度也会使用 100ps,时间单位大小没有影响,#1.207 延时依然对应12ns。
5、`default_nettype
该指令用于指定隐含声明线网的类型,可选类型有none、wire、wand、wor、tri 、triand、trior、tri0、tri1,默认为wire类型。多次使用`default_nettype的话,最新定义的起作用。
注意:如果把`default_nettype设置为none,那么所有的线网都要声明,否则会报错。例如,
//均未声明wire类型,编译器会报Error
`default_nettype none
module test
(
input A,
input B,
output C
);
assign C = A & B;
assign C1 = A & C;
endmodule
部分编译器即使使用`default_nettype none,他仅仅会报错C1,其他变量则不会报错,因为他依旧会默认将输入输出端口默认类型为wire,而外部变量则要求必须声明wire类型才行。我的建议是如果使用`default_nettype none,则声明全部类型,包括端口定义。
6、`resetall
该指令将所有的编译指令重新设置为缺省值。`resetall 可以使得缺省连线类型为线网类型。当 `resetall 加到模块最后时,可以将当前的 `timescale 取消,防止进一步传递,只保证当前的 `timescale 在局部有效,避免 `timescale 的错误继承。
7、`unconnected_drive, `nounconnected_drive
在模块实例化中,出现在这两个编译指令间的任何未连接的输入端口,为正偏电路状态或者为反偏电路状态。`unconnected_drive可以取值为pull1或者pull0。例如,
`unconnected_drive pull1
//在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平)
`nounconnected_drive
`unconnected_drive pull0
//在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平)
`nounconnected_drive
结语:路漫漫其修远兮,吾将上下而求索。
标签:timescale,drive,编译,指令,Verilog,模块,define From: https://www.cnblogs.com/Bruceson/p/18107800