Verilog的基础知识

2023-11-19

Verilog的基本介绍:

硬件描述语言发展至今已有二十多年历史,当今业界的标准中( IEEE标准)主要有VHDL和Verilog HDL 这两种硬件描述语言。
一个设计往往从系统级设计开始,把系统划分成几个大的基本的功能模块,每个功能模块再按一定的规则分成下一个层次的基本单元,如此一直划分下去。自顶向下的设计方法可用下面的树状结构表示:

主要功能


1, 基本逻辑门,例如and 、 or 和nand 等都内置在语言中。
2, 开关级基本结构模型,例如pmos 和nmos 等也被内置在语言中。
3, 可采用三种不同方式或混合方式对设计建模。这些方式包括:行为描述方式—使用过程化结构建模;数据流方式—使用连续赋值语句方式建模;结构化方式—使用门和模块实例语句描述建模。
4, Verilog HDL 中有两类数据类型:线网数据类型和寄存器数据类型。线网类型表示构件间的物理连线,而寄存器类型表示抽象的数据存储元件。
5, 能够描述层次设计,可使用模块实例结构描述任何层次。
6, 设计的规模可以是任意的;语言不对设计的规模(大小)施加任何限制。
7, Verilog HDL 不再是某些公司的专有语言而是I E E E 标准。
8, 人和机器都可阅读Verilog 语言,因此它可作为E D A 的工具和设计者之间的交互语言。
9, 设计能够在多个层次上加以描述,从开关级、门级、寄存器传送级(RT L )到算法级。
10, 能够使用内置开关级原语在开关级对设计完整建模。
11, 同一语言可用于生成模拟激励和指定测试的验证约束条件,例如输入值的指定。
12, Verilog HDL 能够监控模拟验证的执行,即模拟验证执行过程中设计的值能够被监控和显示。这些值也能够用于与期望值比较,在不匹配的情况下,打印报告消息。
13, 在行为级描述中, Verilog HDL 不仅能够在RT L 级上进行设计描述,而且能够在体系结构级描述及其算法级行为上进行设计描述。
14, 能够使用门和模块实例化语句在结构级进行结构描述。
15, 对高级编程语言结构,例如条件语句、情况语句和循环语句,语言中都可以使用。
下图显示了Verilog HDL 的混合方式建模能力,即在一个设计中每个模块均可以在不同设计层次上建模。

模块


模块(module)是Verilog 的基本描述单位,用于描述某个设计的功能或结构及与其他模块通信的外部端口。
模块在概念上可等同一个器件就如我们调用通用器件(与门、三态门等)或通用宏单元(计数器、 ALU、 CPU)等,因此,一个模块可在另一个模块中调用。
一个电路设计可由多个模块组合而成,因此一个模块的设计只是一个系统设计中的某个层次设计,模块设计可采用多种建模方式。
 

例[1] 加法器
module addr (a, b, cin, count, sum);
input [2:0] a;
input [2:0] b;
input cin;
output count;
output [2:0] sum;
assign {count,sum} = a +b + cin;
endmodule
例[2] 比较器
module compare (equal, a, b);
input [1:0] a,b; // declare the input signal ;
output equare ; // declare the output signal;
assign equare = (a == b) ? 1:0 ;
/ * if a = b , output 1, otherwise 0; */
endmodule

/* .... */ 和 // ... 表示注释部分


模块的端口定义部分:


如上例: module addr (a, b, cin, count, sum); 其中module 是模块的保留字, addr 是模块的名字,相当于器件名。()内是该模块的端口声明,定义了该模块的管脚名,是该模块与其他模块通讯的外部接口,相当于器件的pin 。
模块的内容,包括I/O说明,内部信号、调用模块等的声明语句和功能定义语句。
I/O说明语句如: input [2:0] a; input [2:0] b; input cin; output count; 其 中 的 input 、output、 inout 是保留字,定义了管脚信号的流向, [n:0]表示该信号的位宽(总线或单根信号线)。

逻辑功能描述部分如: assign  d_out = d_en ? din :'bz;

对每个模块都要进行端口定义,并说明输入、输出口,然后对模块的功能进行逻辑描述,当然,对测试模块,可以没有输入输出口。
除endmodule 语句外,每个语句后面需有分号表示该语句结束。
 

时延


信号在电路中传输会有传播延时等,如线延时、器件延时。时延就是对延时特性的HDL描述。举例如下:
assign # 2 B = A;
表示 B信号在2个时间单位后得到A信号的值。如下图:
 

在Verilog HDL中,所有时延都必须根据时间单位进行定义,定义方式为在文件头添加如下语句:
`timescale 1ns /100ps
其中’ timescale 是Verilog HDL 提供的预编译处理命令, 1ns 表示时间单位是1ns , 100ps表示时间精度是100ps。根据该命令,编译工具才可以认知 #2 为2ns。

三种建模方式
 

主要有结构化描述方式、数据流描述方式和行为描述方式
结构化描述方式
结构化的建模方式就是通过对电路结构的描述来建模,即通过对器件的调用( HDL概念称为例化),并使用线网来连接各器件的描述方式。这里的器件包括Verilog HDL的内置门如与门and,异或门xor等,也可以是用户的一个设计。结构化的描述方式反映了一个设计的层次结构。
一位全加器
 

module FA_struct (A, B, Cin, Sum, Count);
input A;
input B;
input Cin;
output Sum;
output Count;
wire S1, T1, T2, T3;
// -- statements -- //
xor x1 (S1, A, B);
xor x2 (Sum, S1, Cin);
and A1 (T3, A, B );
and A2 (T2, B, Cin);
and A3 (T1, A, Cin);
or O1 (Cout, T1, T2, T3 );
endmodule

该实例显示了一个全加器由两个异或门、三个与门、一个或门构成。 S1、 T1、 T2、 T3则是门与门之间的连线。代码显示了用纯结构的建模方式,其中xor 、 and、 or 是Verilog HDL 内置的门器件。以 xor x1 (S1, A, B) 该例化语句为例:xor 表明调用一个内置的异或门,器件名称xor ,代码实例化名x1(类似原理图输入方式)。括号内的S1, A, B 表明该器件管脚的实际连接线(信号)的名称 ,其中 A、 B是输入, S1是输出

数据流描述方式
数据流的建模方式就是通过对数据流在设计中的具体行为的描述的来建模。最基本的机制就是用连续赋值语句。在连续赋值语句中,某个值被赋给某个线网变量(信号),语法如下:
assign [delay] net_name = expression;
如: assign #2 A = B;
在数据流描述方式中,还必须借助于HDL提供的一些运算符,如按位逻辑运算符 :逻辑与(&),逻辑或(|)等。
一位全加器:

`timescale 1ns/100ps
module FA_flow(A,B,Cin,Sum,Count)
input A,B,Cin;
output Sum, Count;
wire S1,T1,T2,T3;
assign # 2 S1 = A ^ B;
assign # 2 Sum = S1 ^ Cin;
assign #2 T3 = A & B;
assign #2 T1 = A & Cin;
assign #2 T2 = B & Cin ;
endmodule

注意在各assign 语句之间,是并行执行的,即各语句的执行与语句之间的顺序无关。如上,当A有个变化时, S1、 T3、 T1 将同时变化, S1的变化又会造成Sum的变化。

行为描述方式
行为方式的建模是指采用对信号行为级的描述(不是结构级的描述)的方法来建模。在表示方面,类似数据流的建模方式,但一般是把用initial 块语句或always 块语句描述的归为行为建模方式。行为建模方式通常需要借助一些行为级的运算符如加法运算符(+),减法运算符(-)等。
以下举个例子,对initial 和always 语句的具体应用可看相关章节的介绍,这里,先对行为建模方式有个概念。
 

例[1] 一位全加器的行为建模
module FA_behav1(A, B, Cin, Sum, Cout );
input A,B,Cin;
output Sum,Cout;
reg Sum, Cout;
reg T1,T2,T3;
always@ ( A or B or Cin )
begin
Sum = (A ^ B) ^ Cin ;
T1 = A & Cin;
T2 = B & Cin ;
T3 = A & B;
Cout = (T1| T2) | T3;
end
endmodule

需要先建立以下概念:
1、只有寄存器类型的信号才可以在always和initial 语句中进行赋值,类型定义通过reg语句实现。
2、 always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
3、 always 语句从0 时刻开始。
4、在begin 和end 之间的语句是顺序执行,属于串行语句。

混合设计描述
在实际的设计中,往往是多种设计模型的混合。一般地,对顶层设计,采用结构描述方式,对低层模块,可采用数据流、行为级或两者的结合。两bit 全加器,对顶层模块采用结构描述方式对低层进行例化,对低层模块(FA)可采用结构描述、数据流描述或行为级描述

标识符

标识符( identifier)用于定义模块名、端口名、信号名等。 Verilog HDL 中的标识符( identifier)可以是任意一组字母、数字、 $符号和_(下划线)符号的组合,但标识符的第一个字符必须是字母或者下划线。另外,标识符是区分大小写的。以下是标识符的几个例子:
Count
COUNT //与Count 不同。
R56_68
FIVE$
关键词
Verilog HDL 定义了一系列保留字,叫做关键词,附录A 列出了语言中的所有保留字。注意只有小写的关键词才是保留字。例如,标识符always (这是个关键词)与标识符ALWAYS(非关键词)是不同的。
 

数字值集合


值集合
Verilog HDL中规定了四种基本的值类型:
0:逻辑0或“假”;
1:逻辑1或“真”;
X:未知值;
Z:高阻。
注意这四种值的解释都内置于语言中。如一个为z 的值总是意味着高阻抗,一个为0 的值通常是指逻辑0 。在门的输入或一个表达式中的为“z ”的值通常解释成“x ”。
此外, x 值和z 值都是不分大小写的,也就是说,值0x1z 与值0X1Z 相同。
Verilog HDL 中的常量是由以上这四类基本值组成的。
 

常量
Verilog HDL 中有三种常量:
整型、实型、字符串型。
下划线符号(_)可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提高易
读性;唯一的限制是下划线符号不能用作为首字符。
下面主要介绍整型和字符串型。


整型
整型数可以按如下两种方式书写:
1) 简单的十进制数格式
2) 基数格式
A. 简单的十进制格式
这种形式的整数定义为带有一个可选的“+”(一元)或“-”(一元)操作符的数字序列。
下面是这种简易十进制形式整数的例子。
32 十进制数32
-15 十进制数-15
B. 基数表示法
这种形式的整数格式为:
[size ] 'base value
size 定义以位计的常量的位长; base 为o 或O(表示八进制), b 或B(表示二进制), d 或D(表示十进制), h 或H (表示十六进制)之一; value 是基于base 的值的数字序列。值x 和z 以及十六进制中的a 到f 不区分大小写。
下面是一些具体实例:
5 'O37 5 位八进制数(二进制 11111 )
4 'D2 4 位十进制数 (二进制0011)
4 'B1x_01 4 位二进制数
7 'Hx 7位x(扩展的x), 即xxxxxxx
4 'hZ 4 位z(扩展的z) , 即zzzz
4 'd-4 非法:数值不能为负
8 'h 2A 在位长和字符之间,以及基数和数值之间允许出现空格
3' b 001 非法: ` 和基数b 之间不允许出现空格
(2+3)'b10 非法:位长不能够为表达式
注意, x (或z )在十六进制值中代表4 位x(或z ),在八进制中代表3 位x(或z ),在二进
制中代表1 位x (或z )。
基数格式计数形式的数通常为无符号数。这种形式的整型数的长度定义是可选的。如果没有
定义一个整数型的长度,数的长度为相应值中定义的位数。下面是两个例子:

'o 721
'h AF
9 位八进制数
8 位十六进制数

如果定义的长度比为常量指定的长度长,通常在左边填0 补位。但是如果数最左边一位为x 或z ,就相应地用x 或z 在左边补位。例如:
10'b10 左边添0 占位, 0000000010
10'bx0x1 左边添x 占位, x x x x x x x 0 x 1
如果长度定义得更小,那么最左边的位相应地被截断。例如:
3 ' b1001 _ 0011 与3'b011 相等
5'H0FFF 与5'H1F 相等

字符串型
字符串是双引号内的字符序列。字符串不能分成多行书写。例如:
"INTERNAL ERROR"
" REACHED->HERE "
用8 位ASCII 值表示的字符可看作是无符号整数。因此字符串是8 位ASCII 值的序列。为存储
字符串“INTERNAL ERROR ”,变量需要8 * 1 4 位。
r e g [1: 8*14] Message;
Message = "INTERNAL ERROR"

数据类型


Verilog HDL 主要包括两种数据类型
线网类型(net type) 和 寄存器类型(reg type)。
线网类型
1. wire 和 tri 定义
线网类型主要有wire 和tri 两种。线网类型用于对结构化器件之间的物理连线的建模。如器件的管脚,内部器件如与门的输出等。以上面的加法器为例,输入信号A, B是由外部器件所驱动,异或门X1的输出S1是与异或门X2输入脚相连的物理连接线,它由异或门X1所驱动。
由于线网类型代表的是物理连接线,因此它不存贮逻辑值。必须由器件所驱动。通常由assign进行赋值。如 assign A = B ^ C;
当一个wire 类型的信号没有被驱动时,缺省值为Z(高阻)。
信号没有定义数据类型时,缺省为 wire 类型。
如上面一位全加器的端口信号 A, B, SUM等,没有定义类型,故缺省为wire 线网类型。
2. 两者区别
tri 主要用于定义三态的线网。

寄存器类型
1. 定义
reg 是最常用的寄存器类型,寄存器类型通常用于对存储单元的描述,如D型触发器、 ROM等。存储器类型的信号当在某种触发机制下分配了一个值,在分配下一个值之时保留原值。但必须注意的是, reg 类型的变量,不一定是存储单元,如在always 语句中进行描述的必须用reg 类型的变量。
reg 类型定义语法如下:
reg [msb: lsb] reg1, reg2, . . . r e g N;
msb 和lsb 定义了范围,并且均为常数值表达式。范围定义是可选的;如果没有定义范围,缺省值为1 位寄存器。例如:

reg [3:0] Sat;
reg Cnt;
// S a t 为4 位寄存器。
//1 位寄存器。

reg [1:32] Kisp, Pisp, Lisp ;
寄存器类型的值可取负数,但若该变量用于表达式的运算中,则按无符号类型处理,如:
reg A ;
A = -1;
则A的二进制为 1111,在运算中, A总按 无符号数15 来看待。
2. 寄存器类型的存储单元建模举例
用寄存器类型来构建两位的D触发器如下:
reg [1: 0] Dout ;
always@(posedge Clk)
Dout <= Din;
用寄存器数组类型来建立存储器的模型,如对2个8位的RAM建模如下:
reg [7: 0] Mem[0: 1] ;
对存储单元的赋值必须一个个第赋值,如上2个8位的RAM的赋值必须用两条赋值语句:
Mem[0] = ’ h 55;
Mem[1] = ’ haa;
对数组类型,请按降序方式,如[7: 0] ;

运算符和表达式

算术运算符
在常用的算术运算符主要是 :
加法(二元运算符):“+”;
减法 (二元运算符): “-”;
乘法(二元运算符):“*”;
在算术运算符的使用中,注意如下两个问题:
1. 算术操作结果的位数长度
算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操作符
左端目标长度决定。考虑如下实例:
reg [3:0] Arc, Bar, Crt;
reg [5:0] Frx;
. . .
Arc = Bar + Crt;
Frx = Bar + Crt;
第一个加的结果长度由Bar , Crt 和A rc 长度决定,长度为4 位。
第二个加法操作的长度同样由Frx 的长度决定( Frx 、 Bat 和Crt 中的最长长度),长度为6位。
在第一个赋值中,加法操作的溢出部分被丢弃;而在第二个赋值中,任何溢出的位存储在结果位Frx [ 4 ]中。
在较大的表达式中,中间结果的长度如何确定?在Verilog HDL 中定义了如下规则:表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包括左端目标)。考虑另一个实例:
wire [4:1] Box, Drt;
wire [5:1] Cfg;
wire [6:1] Peg;
wire [8:1] Adt;
. . .
assign Adt = (Box + Cfg) + (Drt + Peg) ;
表达式右端的操作数最长为6 ,但是将左端包含在内时,最大长度为8 。所以所有的加操作使用8 位进行。例如: Box 和Cfg 相加的结果长度为8 位。
2. 有符号数和无符号数
在设计中,请先按无符号数进行。
关系运算符
关系运算符有:
?>(大于)
?<(小于)
?>=(不小于)
?<=(不大于)
= = (逻辑相等)
! = (逻辑不等)
关系操作符的结果为真( 1 )或假( 0 )。如果操作数中有一位为X 或Z ,那么结果为X 。
例:
23 > 45
结果为假( 0 ),而:
52 < 8'hxFF
结果为x 。
如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添0 补齐。例如:
'b1000 > = 'b01110
等价于:
'b01000 > = 'b01110
结果为假( 0 )。
在逻辑相等与不等的比较中,只要一个操作数含有x 或z,比较结果为未知 ( x),如:
假定:
Data = 'b11x0;
Addr = 'b11x0;
那么:
Data = = Addr 比较结果不定,也就是说值为x 。
逻辑运算符
逻辑运算符有:
&& (逻辑与)
|| (逻辑或)
! (逻辑非)
用法为:(表达式1) 逻辑运算符 (表达式2) ....
这些运算符在逻辑值0(假) 或1(真) 上操作。逻辑运算的结果为0 或1 。例如, 假定:
Crd = 'b0; //0 为假
Dgs = 'b1; //1 为真
那么:
Crd && Dgs 结果为0 (假)
Crd || Dgs 结果为1 (真)
! D g s 结果为0 (假)
按位逻辑运算符
按位运算符有:
?~(一元非):(相当于非门运算)
?&(二元与):(相当于与门运算)
?|(二元或): (相当于或门运算)
?^(二元异或):(相当于异或门运算)
?~ ^, ^ ~(二元异或非即同或) :(相当于同或门运算)
wire [7:0] Dbus;
assign Dbus [7:4] = {Dbus [0], Dbus [1], Dbus[2], Dbus[ 3 ] } ;
/ /以反转的顺序将低端4 位赋给高端4 位。
assign Dbus = {Dbus [3:0], Dbus [ 7 : 4 ] } ;
 

条件语句:

if(Sum < 60)
begin
Grade = C;
Total_C = Total _c + 1;
end
else if(Sum < 75)
begin
Grade = B;
Total_B = Total_B + 1;
end
else
begin
Grade = A;
Total_A = Total_A + 1;
end

case语句:

case (HEX)
4'b0001 : LED = 7'b1111001; // 1
4'b0010 : LED = 7'b0100100; // 2
4'b0011 : LED = 7'b0110000; // 3
4'b0100 : LED = 7'b0011001; // 4
4'b0101 : LED = 7'b0010010; // 5
4'b0110 : LED = 7'b0000010; // 6
4'b0111 : LED = 7'b1111000; // 7
4'b1000 : LED = 7'b0000000; // 8
4'b1001 : LED = 7'b0010000; // 9
4'b1010 : LED = 7'b0001000; // A
4'b1011 : LED = 7'b0000011; // B
4'b1100 : LED = 7'b1000110; // C
4'b1101 : LED = 7'b0100001; // D
4'b1110 : LED = 7'b0000110; // E
4'b1111 : LED = 7'b0001110; // F
default :LED = 7'b1000000; // 0
endcase

case 的缺省项必须写,防止产生锁存器
 

实例化语句
在我另一篇博客有例子

Verilog中模块的实例化_浮若于心的博客-CSDN博客_verilog模块实例化

悬空端口的处理
在我们的实例化中,可能有些管脚没用到,可在映射中采用空白处理,如:
DFF d1 (
.Q(QS),
.Qbar ( ),
.Data (D ) ,
.Preset ( ), // 该管脚悬空
.Clock (CK)
); //名称对应方式。
对输入管脚悬空的,则该管脚输入为高阻 Z,输出管脚被悬空的,该输出管脚废弃不用。


不同端口长度的处理
当端口和局部端口表达式的长度不同时,端口通过无符号数的右对齐或截断方式进行匹配。
例如:
module Child (Pba, Ppy) ;
input [5:0] Pba;
output [2:0] Ppy;
. . .
endmodule
module Top;
wire [1:2] Bdl;
wire [2:6] M p r;
Child C1 (Bdl, Mpr) ;
endmodule
在对Child 模块的实例中, Bdl[2]连接到Pba[ 0 ], Bdl[1] 连接到Pba[ 1 ],余下的输入端口Pba[5]、 Pba[4]和Pba[3]悬空,因此为高阻态z 。与之相似, Mpr[6]连接到Ppy[0], Mpr[5]连接到Ppy[1], Mpr[4] 连接到Ppy[2 ]。参见下图:
 

过程赋值语句


Verilog HDL 中提供两种过程赋值语句 initial 和 always 语句,用这两种语句来实现行为的建
模。这两种语句之间的执行是并行的,即语句的执行与位置顺序无关。这两种语句通常与语句块
(begin ....end)相结合,则语句块中的执行是按顺序执行的。
1. initial 语句
initial 语句只执行一次,即在设计被开始模拟执行时开始( 0时刻)。通常只用在对设计进行
仿真的测试文件中,用于对一些信号进行初始化和产生特定的信号波形。
 

initial
begin
#2 Stream = 1;
#5 Stream = 0;
#3 Stream = 1;
#4 Stream = 0;
#2 Stream = 1;
#5 Stream = 0;
end

always 语句
always 语句与initial 语句相反,是被重复执行,执行机制是通过对一个称为敏感变量表的事件驱动来实现的,下面会具体讲到。 always 语句可实现组合逻辑或时序逻辑的建模。
例[1]:
initial
Clk = 0 ;
always
#5 Clk = ~Clk;
因为always 语句是重复执行的,因此, Clk 是初始值为0 的,周期为10 的方波。
 

例[2] D 触发器
always @ ( posedge Clk or posedge Rst )
begin
if Rst
Q <= ‘ b 0;
else
Q <= D;

上面括号内的内容称为敏感变量,即整个always 语句当敏感变量有变化时被执行,否则不执行。因此,当Rst 为1 时, Q被复位,在时钟上升沿时, D被采样到Q。 有@ 的用来描述一个时序器件。
注意以下几点:
1、对组合逻辑的always 语句,敏感变量必须写全,敏感变量是指等式右边出现的所有标识符
如上的a, b和条件表达式中出现的所以标识符 如上例3的sel。
2、对组合逻辑器件的赋值采用阻塞赋值 “=”
3、时序逻辑器件的赋值语句采用非阻塞赋值 “<=”,如上的 Q 〈= D;
 

"文件包含"处理`include

所谓"文件包含"处理是一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。Verilog HDL语言提供了`include命令用来实现"文件包含"的操作。其一般形式为:

`include "文件名"

在编译的时候,需要对`include命令进行"文件包含"预处理:将File2.v的全部内容复制插入到`include "File2.v"命令出现的地方,即将File2.v被包含到File1.v中,得到图C的结果。在接着往下进行编译中,将"包含"以后的File1.v作为一个源文件单位进行编译。

1)文件aaa.v

module aaa(a,b,out);
input a, b;
output out;
wire out;
assign out = a^b;
endmodule
(2)文件 bbb.v

`include "aaa.v"
module bbb(c,d,e,out);
input c,d,e;
output out;
wire out_a;
wire out;
aaa aaa(.a(c),.b(d),.out(out_a));
assign out=e&out_a;
endmodule

在上面的例子中,文件bbb.v用到了文件aaa.v中的模块aaa的实例器件,通过"文件包含"处理来调用。模块aaa实际上是作为模块bbb的子模块来被调用的。在经过编译预处理后,文件bbb.v实际相当于下面的程序文件bbb.v:

module aaa(a,b,out);
input a, b;
output out;
wire out;
assign out = a ^ b;
endmodule

module bbb( c, d, e, out);
input c, d, e;
output out;
wire out_a;
wire out;
aaa aaa(.a(c),.b(d),.out(out_a));
assign out= e & out_a;
endmodule

关于"文件包含"处理的四点说明:

1) 一个`include命令只能指定一个被包含的文件,如果要包含n个文件,要用n个`include命令。注意下面的写法是非法的`include"aaa.v""bbb.v"

2) `include命令可以出现在Verilog HDL源程序的任何地方,被包含文件名可以是相对路径名,也可以是绝对路径名。例如:'include"parts/count.v"

3) 可以将多个`include命令写在一行,在`include命令行,只可以出空格和注释行。例如下面的写法是合法的。

'include "fileB" 'include "fileC" //including fileB and fileC

4) 如果文件1包含文件2,而文件2要用到文件3的内容,则可以在文件1用两个`include命令分别包含文件2和文件3,而且文件3应出现在文件2之前。

这个`includel里面定义的主要是一些参数,然后给另外的文件进行一个调用

define宏定义+`inlude "file.v"文件包含来实现参数模块化设计

1.新建参数模块文件(我命名为para.v);

  2.在para.v文件中使用'define宏定义参数(部分、有错误): 

     //`define+name+参数  
    `define   STATE_INIT     3'd0
    `define   STATE_IDLE    3'd1
    `define   STATE_WRIT   3'd2
    `define   STATE_READ  3'd3
    `define   STATE_WORK      3'd4
    `define   STATE_RETU  3'd5

  3.在需要调用参数的文件init.v中使用`include "para.v":

    `include "para.v"

  4.在init.v文件需要参数的地方使用`name 调用(部分):

    state_init <= `STATE_INIT;

若直接在module中通过localparam或者parameter进行参数定义的话,会带来两个问题:

    1.代码长度增加,不够美观;

    2.不利于参数和代码修改;

`define 与localparam和parameter最大的区别就是`define 可以跨文件传递参数;parameter只能在模块间传递参数;localparam只能在其所在的module中起作用,不能参与参数传递。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Verilog的基础知识 的相关文章

  • Tcl脚本学习

    包的创建和调用 在tcl脚本中 我们可以通过创建和调用包来增强代码的可复用性 创建包的步骤 1 在包脚本文件中 首先声明 package provide 标识当前文件提供了一个包 之后在该文件中完成包的内容 2 通过pkg mkIndex命
  • 在vivado中使用tcl脚本(UG894)

    本文源自UG894 主要介绍如何在vivado中使用tcl脚本 1 vivado中如何获取tcl help vivado中任何自带的命令都可以通过 help 获取帮助信息 也可以直接输入 help 取得vivado命令合集 并通过 help
  • FPGA面试真题解析(3)

    9 寄存器的Tsu 建立时间 是如何定义的 硬件逻辑实习岗 A 在时钟沿到来之后数据保持稳定的时间 B 在时钟沿带来前后数据都需要保持稳定的时间 C 在整个时钟周期数据保持稳定的时间 D 在时钟沿到来之前数据保持稳定的时间 解析 考察数字电
  • [FPGA系列] 扩展知识 --- 时钟小结

    一 基本概念 时钟域 由同一个时钟信号控制的区域 时钟抖动 Jitter 相对于理想时钟信号 实际时钟信号存在时而超前 时而之后的偏移 时钟偏斜 Skew 时钟信号到达数字电路各个部分所用时间的差异 时钟漂移 Wander 工程上解释 抖动
  • Xilinx平台SRIO介绍(二)SRIO IP核基础知识

    使用SRIO IP核必须掌握的基础知识 理解了这篇 剩下的只是代码罢了 汇总篇 Xilinx平台SRIO介绍 汇总篇 目录 前言 SRIO RapidIO GT 有什么关系
  • FPGA实战--等精度频率测量

    首先放置效果图 本次试验中采用的是等精度测频率 等精度测频的原理是产生一个1s的高电平 在高电平中对被测方波进行计数 所测得数字即该波形频率 具体等精度测量原理请参考 http www elecfans com d 591858 html
  • 【Xilinx DDR3 MIG】Xilinx FPGA DDR3读写实验相关用户接口引脚解释

    目录 DDR3读写实验 实验框图 时钟模块 DDR3读写及LED指示模块 MIG IP核 用户接口解释
  • Verilog的基础知识

    Verilog的基本介绍 硬件描述语言发展至今已有二十多年历史 当今业界的标准中 IEEE标准 主要有VHDL和Verilog HDL 这两种硬件描述语言 一个设计往往从系统级设计开始 把系统划分成几个大的基本的功能模块 每个功能模块再按一
  • FPGA Xilinx 7系列高速收发器GTX通信

    Xilinx 7系列高速收发器GTX 说明 FPGA TX端 zynq 7z035 RX端 zynq 7z100 两个FPGA通过SFP 光纤 接口相连进行GTX的通信 环境 Vivado2018 2 IP核 7 Series FPGAs
  • [HDLBits] Exams/ece241 2014 q7a

    Design a 1 12 counter with the following inputs and outputs Reset Synchronous active high reset that forces the counter
  • 基于FPGA的AHT10传感器温湿度读取

    文章目录 一 系统框架 二 i2c接口 三 i2c控制模块 状态机设计 状态转移图 START INIT CHECK INIT IDLE TRIGGER WAIT READ 代码 四 数据处理模块 串口 代码 五 仿真 testbench设
  • VHDL——连接开关和LED

    我有 Xilinx Spartan6 和下一个 VHDL 代码 library ieee use ieee std logic 1164 all use ieee numeric std all entity Switches Leds i
  • 在 C 中操作 80 位数据类型

    我正在用 C 实现一些加密算法 其中涉及 80 位密钥 特定操作涉及将密钥旋转移位 x 个位数 我已经尝试过 long double 类型 如果我没记错的话 它是 80 位 但这不适用于位移运算符 我能想到的唯一替代方案是使用 10 个元素
  • 同时读取和写入寄存器

    我计划在 FPGA 上用 VHDL 设计一个类似 MIPS 的 CPU CPU 将具有经典的五级管道 没有转发和危险预防 在计算机体系结构课程中 我了解到第一个 MIPS CPU 用于在时钟上升沿读取寄存器文件并在时钟下降沿写入 我使用的F
  • 修改后的 baugh-wooley 算法乘法 verilog 代码不能正确乘法

    以下 verilog 源代码和 或测试平台可以很好地工作商业模拟器 iverilog https www edaplayground com x 3TuQ也形式化验证工具 yosys smtbmc https gist github com
  • PyOpenCL 中的时间测量

    我正在 FPGA 和 GPU 中使用 PyOpenCL 运行内核 为了测量执行所需的时间 我使用 t1 time event mykernel queue c width c height block size block size d c
  • if 语句导致 Verilog 中的锁存推断?

    我正在编写用于合成算法的 Verilog 代码 我对哪些情况可能导致推断锁存器有点困惑 下面是这样的一段代码 虽然它在模拟中工作得很好 但我担心它可能会导致硬件问题 always b1 or b2 b1 map b2 map m1 map
  • 如何使用 Verilog 和 FPGA 计算一系列组合电路的传播延迟?

    我是 FPGA 和 HDL 的新手 但我正在尝试学习 但无法弄清楚这一点 如何通过多个级别的组合逻辑来计算或估计传播延迟 我可以仅凭经验确定这一点 还是可以在设计时弄清楚 在这种情况下 我使用 FPGA 来实现奇偶校验设置和检查电路 该电路
  • FPGA 有哪些实际应用?

    我对我的程序为一个小型七段显示器提供动力感到非常兴奋 但是当我向不在现场的人展示它时 他们总是说 那么你能用它做什么 我永远无法给他们一个简洁的答案 谁能帮我吗 第一 它们不需要具有易失性存储器 事实上 大厂商 Xilinx Altera
  • 从 OpenCV 代码到 FPGA 代码的转换是否比 Matlab 代码更容易? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想做一个关于图像处理的项目 我想知道如果我想在FPGA上实现这个项目 我应该在第一阶段选择Matla

随机推荐

  • 极速入门体验Qt5软件开发,从安装到打包,少走弯路,Qt入门指南,串口调试助手开发实战

    文章目录 前言 一 成果先行 二 下载安装 1 安装QT 三 项目开发实战 1 创建新项目 2 UI设计 3 编写widget h头文件 4 编写widget cpp源文件 四 编译运行 五 项目打包 1 编译发布版 2 绿色版打包 3 安
  • python 调用matlab的.m文件

    最近在找算法的时候扒到一篇有用matlab写的算法 但我平时用的都是python 所以在网上找了有关python调用matlab m文件的教程 但或多或少都有点问题 经过不断尝试总算成功了 先说下软件版本我用matlab是R2020a py
  • 为多用户安装conda_Conda在中文用户名下运行

    让Conda在中文用户名下运行 本实验仅测试于Windows10系统中 理论上这个方法可以适应任何系统 核心是修改 condarc文件中的参数路径 使其脱离中文 关于如何使用conda anaconda miniconda 可以参照我这个博
  • SSM + Activiti5 简单OA系统

    介绍 本项目是为简单版自动化办公流程 项目内置 出差报销流程 可以作为熟悉了解Activit流程引擎学习项目 软件涉及技术 Spring4 SpringMVC4 MyBatis3 MySQL8 Pagehelper 分页控件 Activit
  • python-pickle模块

    python3 pickle持久化的储存数据 python程序运行中得到了一些字符串 列表 字典等数据 想要长久的保存下来 方便以后使用 而不是简单的放入内存中关机断电就丢失数据 python模块大全中pickle模块就排上用场了 他可以将
  • 最先进的深度学习:Mask R-CNN简介

    介绍 Introduction From my experience as a time traveller I can confidently say that autonomous driving is was will be all
  • android dm-verity 功能

    Android dm verity 实现原理深入研究 思维导图 dm verity 说明 源码基于 SC20 平台 Android5 1 Android dm verify overview 目录 Android dm verify ove
  • 协方差矩阵的实例与意义

    协方差矩阵的实例与意义 在机器学习中经常需要计算协方差矩阵 本科时没学过这个概念 一直对此非常头疼 现在试图通过实例的计算 图形化的表示来梳理一下什么是协方差矩阵 A numerical example 问题 有一组数据 如下 分别为二维向
  • Visual Studio 2022配置PCL1.12.1版本点云库

    说明 这个配置步骤是当时自己参考2019配置的 当时网上还没有VS2022的配置步骤 我在自己电脑上是配置成功了 所以我将配置过程记录了下来 仅供参考 1 软件下载 Microsoft Visual Studio 2022 Pro http
  • Kali 实现ARP断网攻击_arp断网攻击_arp欺骗

    1 安装软件包 在中端中执行 apt install dsniff ssldump 2 搜索局域网内的ip地址 nmap sn 192 168 0 这里的192 168 0 有的是192 168 1 执行结果 Nmap scan repor
  • SQLite外键(Foreign Key) 的使用例子

    从SQLite 3 6 19 开始支持 外键约束 sqlite gt PRAGMA foreign keys 0 sqlite gt PRAGMA foreign keys ON sqlite gt PRAGMA foreign keys
  • 机器学习:k近邻算法(KNN)介绍

    k近邻算法是一种最简单最经典的机器学习算法之一 该算法的原理为 当对测试样本进行分类时 首先通过扫描训练样本集 找到与该测试样本最相似的k个训练样本 根据这个样本的类别进行投票确定测试样本的类别 也可以通过个样本与测试样本的相似程度进行加权
  • 并发编程(二)——内存模型

    前言 欢迎大家一起来学习多线程 大家一起来学习吧 并发编程 一 多线程快速入门 并发编程 二 内存模型 并发编程 三 多线程之间如何实现通讯 并发编程 四 JUC并发包常用方法介绍 并发编程 五 线程池及原理剖析 并发编程 六 java中锁
  • linux给用户添加sudo权限

    切换到拥有sudo权限的用户下 输入命令 sudo vim etc sudoers 开始编辑 etc sudoers文件 找到 root ALL ALL ALL ALL 这一 行 在它下面添加 xxx ALL ALL ALL ALL 这里的
  • 数组对象在ts中的用法

    数组对象在TS中的用法 length长度 let songs string red blue pink console log songs length push push 方法将一个或多个元素添加到数组的末尾 并返回该数组的新长 3 fo
  • Unity3D 性能优化

    优化思路 个人优化原则 三原则 注意细节 注意细节 注意细节 优化手段 1 善于使用工具 2 减少总量 3 空间 时间互换 4 由浅入深 1 善于使用工具 一定要善于使用工具来分析性能问题 Profiler 先找出性能瓶颈再做优化 2 减少
  • 菜鸟教程《Python 3 教程》笔记(19):错误与异常

    菜鸟教程 Python 3 教程 笔记 19 19 错误和异常 19 1 assert 断言 19 2 异常处理 19 2 1 try except 19 2 2 try except else 19 2 3 try finally 语句
  • JAVA获取类的类对象的三种方式

    自定义一个类 MyClass 并声明该类的对象 class MyClass MyClass mClass1 new MyClass 1 2 3 在上面说过 Class 类的构造方法是私有的 只有 java 虚拟机可以调用该方法创建该类的对象
  • Linux下Qt 5.15.2源码下载及编译

    一 下载 Qt的官方下载地址 Qt Downloads Qt 5 15 2源码下载路径 archive qt 5 15 5 15 2 single qt everywhere src 5 15 2 zip 二 编译源码 Qt官网提供了编译前
  • Verilog的基础知识

    Verilog的基本介绍 硬件描述语言发展至今已有二十多年历史 当今业界的标准中 IEEE标准 主要有VHDL和Verilog HDL 这两种硬件描述语言 一个设计往往从系统级设计开始 把系统划分成几个大的基本的功能模块 每个功能模块再按一