Verilog基础
文章平均质量分 89
Verilog基础
日晨难再
杂学旁收
展开
-
Verilog基础:简单标识符和转义标识符
标识符(identifier)是一个为了引用而给一个对象起的名字。一个标识符可以是一个简单标识符,也可以是一个转义标识符。本文将对两者进行详细阐述。原创 2024-07-15 14:19:56 · 420 阅读 · 5 评论 -
Verilog基础:操作数的位选(bit-select)和域选(part select)
Verilog基础:操作数的位选(bit-select)和域选(part select)原创 2024-07-12 16:40:15 · 600 阅读 · 3 评论 -
Verilog基础:在testbench中使用阻塞赋值和非阻塞赋值的区别
本文详细阐述了在一个testbench中,应该如何使用阻塞赋值与非阻塞赋值。首先说结论,建议在testbench中,对时钟信号(包括分频时钟)使用阻塞赋值,对其他同步信号使用非阻塞赋值。原创 2024-03-26 19:18:30 · 1926 阅读 · 35 评论 -
Verilog基础:always结构和initial结构
always和initial是Verilog中的核心,它们被称为结构(construct),用于组织语句的执行方式。下面将分别对这两者进行阐述。原创 2024-03-20 11:12:39 · 1018 阅读 · 8 评论 -
Verilog基础:强度建模与net型信号的多驱动问题(三)
在Verilog基础:强度建模与net型信号的多驱动问题(二)-CSDN博客一文中,我们已经学会了多个拥有单个强度和确定值的net型信号的相与组合的规则,本文将学习更为普遍的net型信号相与的规则,首先我们说明一下一些特殊的net型信号。原创 2024-01-22 19:04:39 · 1993 阅读 · 19 评论 -
Verilog基础:强度建模与net型信号的多驱动问题(二)
首先来说明一下什么叫信号拥有单个强度和确定值,其实如果一个net型信号拥有单个强度,那它一定拥有确定值。首先我们把上一章中的比例尺给出,如图4所示。下面举例说明单个强度和确定值的定义。原创 2024-01-19 21:51:24 · 1231 阅读 · 24 评论 -
Verilog基础:强度建模与net型信号的多驱动问题(一)
Verilog HDL提供了针对线网信号0、1、x、z的精准强度建模方式,这样可以允许将两个线网信号进行线与操作从而更加精确地描述出硬件行为。 强度建模可以在两个地方使用,一个是连续赋值语句,另一个是门级建模。一个强度由两部分组成,一部分表示信号0的强度,称为strength0;一部分表示信号1的强度,称为strength1。原创 2024-01-18 21:33:25 · 1830 阅读 · 23 评论 -
Verilog基础:$random系统函数的使用
$random系统函数在每次调用时返回一个32位的随机数,这个随机数是有符号的,可正可负。按照Verilog标准语法,$random系统函数的调用方式为$random或$random(seed),但实际上$random()这种调用方式也是可以的,且其与$random完全一样。原创 2023-12-10 20:42:07 · 847 阅读 · 18 评论 -
Verilog基础:时序调度中的竞争(三)(#0的使用)
作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序的,然而Verilog标准并没有将这些事件调度的顺序定死,而是给予了仿真器厂商一定的自由去实现自己的产品,这就导致了设计者如果不遵循一定的编程习惯,会导致意想不到的仿真结果,下面是一些相关的规则。中所说,被触发的三个always结构的执行顺序是不定的,但由于这里有#0,导致了#0 $display("The initial_1 execute");中竞争的例子加以说明。原创 2023-12-09 15:35:59 · 1209 阅读 · 19 评论 -
Verilog基础:寄存器输出的两种风格
对于状态机简单的输出寄存,可以将输出组合逻辑和输出寄存融合,比如计数器(对计数器而言状态就是输出,所以也可以理解为将状态转移也融合进来了)。同时对于一般简单的寄存器操作比如移位,也可以将输出组合逻辑和输出寄存融合。例如状态机中的状态转移,实际上就是一种寄存器操作,因为这相当于将下一状态的组合逻辑连接至寄存器的输入,如图一的Moore状态机所示。但对于需要输出寄存的情况,就可能出现两种不同的描述寄存器操作的风格,一种是组合逻辑和寄存器操作分离,就像状态转移一样,另一种是将组合逻辑和寄存器操作混合在一起。原创 2023-12-09 21:02:42 · 540 阅读 · 12 评论 -
Verilog基础:$time、$stime和$realtime系统函数的使用
Verilog基础和这三个系统函数提供了返回当前仿真时间方法。注意,这里的仿真时间的最小分辨能力是由仿真时间精度决定的,简单来说,可以理解为仿真时间精度是仿真器维护的仿真时间的最小单位(没有小数部分),而仿真时间精度由层次化设计中所有模块的时间精度中最小的决定,如下面的例子所示。仿真时间精度也是仿真能推进的最小时间。原创 2023-12-05 21:04:10 · 1425 阅读 · 15 评论 -
Verilog基础:编译指令`timescale
而time_precision参数指定了时间精度,一个层次化设计的所有模块中最小的时间精度决定了仿真的时间精度,需要注意的是,仿真的时间精度并不一定和各模块的时间精度相同,这也就是说一个模块可能显示出比自己仿真精度还小的时间值。时间精度不能比时间单位还大,也就是说精度最大与时间单位相同,这很好理解,如果一个时间精度都大于时间单位了,那它将成为实际意义上的时间单位。最后顺带一提,仿真时间精度也是仿真能推进的时间精度,在上例中,无法以500fs为步长推进仿真时间,无论你推进了多少次。编译指令的语法如下所示。原创 2023-12-05 15:33:08 · 605 阅读 · 14 评论 -
Verilog基础:时序调度中的竞争(二)(创建分频时钟时,使用阻塞赋值)
作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序的,然而Verilog标准并没有将这些事件调度的顺序定死,而是给予了仿真器厂商一定的自由去实现自己的产品,这就导致了设计者如果不遵循一定的编程习惯,会导致意想不到的仿真结果,下面是一些相关的规则。但这不是绝对的,当这个寄存器操作的对象是生成时钟时,如果使用了非阻塞赋值,就有可能造成仿真出现错误,下面就是一个时钟竞争的例子。下面是修改后没有竞争的波形。原创 2023-11-27 15:22:06 · 1652 阅读 · 26 评论 -
Verilog基础:时序调度中的竞争(一)(不要在两个及以上的always或initial结构中对同一个变量赋值)
当a赋值后,always @(a)被调度了,但他不一定会在b赋值之前执行,有可能在执行完b赋值、c赋值之后再来执行always @(a),此时always @(b)和always @(c)也应该在队列中,他们执行的先后顺序是标准没有保证的(但需要注意的是,最基本的调度者和被调度者的先后关系是无法改变的,即always @(a)一定在a赋值后,b、c亦然)。一个更好的做法是给$display语句一定的延时,这样就能确保在执行$display前,连续赋值已经执行完毕,因为不同时间的语句执行是不会产生竞争的。原创 2023-11-24 22:37:19 · 1205 阅读 · 17 评论 -
Verilog基础:仿真时x信号的产生和x信号对于各运算符的特性
Verilog基础信号爆x也许是所有IC人的噩梦,满屏的红色波形常让人头疼不已,但x信号的产生原因却常常只有几种,只要遵循一定的代码规范,就可以避免产生信号中出现x的问题。最常见问题就是使用了未初始化的reg型变量,因为reg型变量在被创建后使用默认值x。如果在初始化变量之前在其他地方提前使用了,便有可能造成x态的传播。为了避免,可以给所有时序逻辑中用到的reg型变量赋初值(不可综合),但更为推荐的是为所有时序逻辑中使用到的reg型变量添加复位逻辑(可综合)并确保复位,如下所示。原创 2023-11-18 00:21:07 · 2926 阅读 · 16 评论 -
Verilog基础:三段式状态机与输出寄存
这两类有限状态机的下一状态和输出都是组合逻辑的形式的(指输出不直接来自寄存器的输出),两类状态机的结构如图1、图2所示。图4和图5分别给出了寄存输出的Mealy型状态机和Moore型状态机的结构。上面两图不难理解,但是一个新的问题出现了,即输出会延后一个周期得到,如果既需要当前周期给出输出,又需要对输出寄存,就不能使用当前状态和输入确定输出,而是应该使用下一状态组合逻辑和输入确定输出。对于Mealy状态机,因为需要状态转移和相应状态的输出同时出现,输出寄存器需要保存由下一状态组合逻辑和的输入推导的输出。原创 2023-11-13 19:04:22 · 2454 阅读 · 11 评论 -
Verilog基础:$fopen和$fclose系统函数、任务的使用
FD为1,他的低31位用来打开文件,FD不使用独热码,因此它可以打开2的31次方个文件(包括三个预先打开的STDIN、STDOUT和STDERR),但失去了MCD句柄可以相与的优势,所以FD不能同时操作多个文件,不过FD可以决定以读、写、读和写以及追加的形式打开文件。最初,在Verilog-1995标准中,最多同时打开的32个文件中,包括一个已经提前打开的用于输出的文件STDOUT,工程师在做验证时就很受限制,因为有时候需要同时打开超过31个文件,需要更好的文件I/O功能。原创 2023-10-22 23:45:35 · 788 阅读 · 11 评论 -
Verilog基础:避免混合使用阻塞和非阻塞赋值
这种混杂的编码风格意味着:当与非门的输入发生变化时,组合信号d不会发生变化,组合信号d发生变化的唯一时刻是在时钟的有效沿或复位。对于大型的设计,工程师要花费很多时间去理解这种怪异的行为——触发器的输入和对应的输出在同一个沿变化,这在真实的硬件上是不会发生的,只是这种编码风格产生的副作用。我们可以看到这种在同一个always块内混杂阻塞和非赋值赋值的编码风格有的缺点:仿真性能差,可读性差(需要对Verilog事件调度有很好的理解),不容易编码(可能以错误的方式混杂了两种赋值,波形令人困惑)。原创 2023-10-19 17:27:45 · 948 阅读 · 6 评论 -
Verilog基础:标识符的层次名引用(二)
如果上级模块的名字,或模块实例的名字已知,则变量可以被引用。第一种方法是使用模块名引用上层模块的信号,具体过程为,首先搜索本层次(Below模块)有无名字为Middle的层次,然后向上推进到Middle模块的最外层,此时仍然没有Middle层次(本模块名在本模块内不可见),最后搜索Top模块,发现例化了Middle模块,则可以确定x的位置。第二种方法是使用实例名,与第一种方法类似,不同的是,此时的指向更为清晰,明确指定了是middle_0实例,而第一种方法使用模块名,指的是层次包括了信号使用处层次的实例。原创 2023-06-23 12:20:41 · 865 阅读 · 6 评论 -
Verilog基础:$readmemb和$readmemh系统任务的使用与其中的初始化地址相关问题(详细细节)
在读取有地址标号的文件时,首先会定位到地址和起始地址相同的那条数据(当没有起始地址时,是定位到存储器最低位对应的地址),然后开始从左到右,从上到下,一条一条数据依次读取,直到文件结束(所以可能会出现初始化覆盖的情况,如下所示),或者有数据的地址超出了范围才结束读取。@和数字之间不允许有空格,可以使用数据文件中所需的任意多的地址规范,当系统任务遇到地址规范时,它会从该内存地址开始加载后续数据,并将数据填入对应地址索引的寄存器变量中。中美元符$和后面的关键词之间必须连续,不能有空白。原创 2023-09-22 12:58:37 · 941 阅读 · 7 评论 -
Verilog基础:延时模型
Verilog基础专栏。原创 2023-08-31 15:02:56 · 1943 阅读 · 8 评论 -
Verilog基础:巴科斯范式(BNF)
最后一个范式定义了variable_lvalue可以是hierarchical_variable_identifier加上可选的[]包围的多个数组表达式索引,以及可选的最后的[]包围的位选或域选表达式,variable_lvalue还可以是使用拼接运算符{}连接起来的多个variable_lvalue(递归定义自己)。第三个范式定义了第一个范式中的delay_or_event_control,为delay_control或event_control或使用repeat语句的event_control。原创 2023-08-29 18:38:47 · 356 阅读 · 9 评论 -
Verilog基础:块语句
块语句(block statements)是一种把语句组织在一起,这样他们在语法上就像单个语句一样工作。Verilog HDL中有两种类型的块:顺序块,也叫begin-end块并行块,也叫fork-join块 顺序块应该由关键词begin和end分隔,顺序块中的过程语句应该按照它们在块中给出的顺序依次执行。 并行块应该由关键词fork和join分隔,并行块中的过程语句并发执行(这里的并发执行不是指严格在同时有两个语句执行,而是指在同一个仿真时间同时执行,因为实际上仿真原创 2023-08-29 16:14:26 · 484 阅读 · 18 评论 -
Verilog基础:disable语句
disable语句提供了终止并发活动过程的能力,同时保持了Verilog过程描述的结构化本质。disable语句在处理意外情况时很有用,例如硬件中断或全局复位。disable语句可以有如下用途。1、提前结束task的执行。2、终止命名块的执行,执行后面的语句(类似于C语言的goto)。3、跳出循环语句(类似于C语言的break)。4、跳出循环中的后续语句(类似于C语言的continue)。原创 2023-07-06 13:02:13 · 2836 阅读 · 5 评论 -
Verilog基础:标识符的层次名引用(一)
任何命名的Verilog对象或者说层次化名字引用都可以通过连接包含它的模块名称、模块实例名称、生成块、任务、函数或命名块的名称以其完整的形式唯一地引用。模块中的每个模块实例(包括数组实例)、生成块实例、任务定义、函数定义以及命名块都定义了层次结构的新分支。任务、函数和命名块中的命名块也定义了层次结构的新分支。未命名的生成块是例外,它们创建的分支仅在块内和块内实例化的任何层次中可见。名字的层次化结构可以被视为树结构,其中每个模块实例、生成块实例、任务、函数或命名块在树的特定分支中定义了新的层次级别或作用域。原创 2023-06-10 22:15:31 · 1085 阅读 · 6 评论 -
Verilog基础:task和function的使用(二)
让我们考虑一个简单的RAM模型,为了使这个模型参数化,我们需要地址的宽度、存储的深度和数据的宽度。数据的宽度必须传递给模型,但对于地址的宽度和存储的深度,就只需要传递一个即可。4、没有使用automatic的function是静态的(Static),所有在function中声明的输入参数和函数内项目都是静态分配内存的,对于所有并发执行的同一个function,他们是共享的。5、使用automatic的function是动态的,可重入的,仿真器为每个并发执行的function动态地分配内存。原创 2023-06-08 16:32:09 · 491 阅读 · 5 评论 -
Verilog基础:表达式中的整数常量(integer)
合法的基数指定是d、D、h、H、o、O、b或B,分别表示十进制、十六进制、八进制和二进制的基。在第二种表现形式中,如果第三个标记中的无符号数字的位宽小于位宽常数指定的大小,则无符号数字会在左边填0直到大小吻合(这里并不会因为有s指示符而进行符号拓展),如果无符号数字的最高位是x或z,则会向左填充x或z。第三个标记是无符号数字,应包含对指定基数合法的数字(例如对于十进制,不能出现a-f的字母),第三个标记和第二个标记的字母间可以添加空格,十六进制使用到的a-f不区分大小写,可能使用到的x和z也不区分大小写。原创 2023-06-07 23:12:30 · 4513 阅读 · 6 评论 -
Verilog基础:task和function的使用(一)
任务(task)和函数(function)即提供了从不同位置执行公共过程的能力(因为这样可以实现代码共享),也提供了把大过程分解成小过程的能力(因为小过程更便于阅读和调试)。下面将介绍task和funtion之间的不同点,介绍如何定义和调用task和function。注意:函数和任务都是可以综合的,但是有诸多的要求和限制,所以要谨慎使用。原创 2023-04-24 23:13:10 · 3529 阅读 · 5 评论 -
Verilog基础:casex和full_case、parallel_case的使用
相关文章 Verilog基础:表达式位宽的确定(位宽拓展) Verilog基础:表达式符号的确定Verilog基础:数据类型Verilog基础:位宽拓展和有符号数运算的联系Verilog基础:case、casex、casez语句目录1.casex的误用2.casez的误用3.full_case和parallel_case3.1 full_case 3.2 不是full的case语句3.3 是full的case语句3.4 使用full_case综合指令3.5 full_case综合指原创 2023-04-20 14:46:27 · 2270 阅读 · 2 评论 -
Verilog基础:case、casex、casez语句
Verilog中的case语句是多路决策语句,用于检查一个表达式的值是否与其他多个表达式的值相等,如果发现匹配,则进行分支跳转,执行相应语句。就像是C语言中的switch语句一样,但Verilog中的case语句还有以下特性:1.除了case,还支持casez和casex变种。2.case_expression和case_item可以是各种数据类型的组合:变量/常量、常量/变量、变量/变量。3.既可以实现平行结构(parallel),也可以实现优先级结构(priority)。原创 2023-04-13 15:07:33 · 5939 阅读 · 1 评论 -
Verilog基础:数据类型
除了trireg之外,所有其他的线网类型均不能保存值,而线网的值是由驱动(driver)决定的,例如由连续赋值驱动或由模块驱动。如果一个线网没有驱动,那么线网的值为高阻z,但是tri0、tri1、trireg除外,tri0是0,tri1是1,而trireg会保存之前的驱动值。对reg的赋值是过程赋值(阻塞赋值和非阻塞复制),且只能在过程块中赋值(always和initial),因为reg能保持每次赋给它的值,所以能被用来对触发器或锁存器等能保存数据的单元,但reg也可以用于对组合逻辑建模。原创 2023-01-18 18:00:10 · 1079 阅读 · 0 评论 -
Verilog基础:位宽拓展和有符号数运算的联系
首先我们发现表达式右端的intA是32位的,根据上下文位宽拓展规则,右端的4位常数会被首先拓展至32位,注意:此时右端的数是一个无符号数(因为在d前没有s符号),所以会被高位补0拓展为000...01100,但由于常数前又有取负运算符,所以最后表达式的结果为111...10100(符号位取反,其他位取反加一),即-12的补码,但此时的表达式结果并不被当做有符号数-12来看,而是解释为一个无符号的大正数,这同样是因为d前没有s符号。原创 2023-01-23 22:39:21 · 1679 阅读 · 1 评论 -
Verilog基础:表达式位宽的确定(位宽拓展)
我们可以首先找到被加入上下文环境的操作数,a和b作为+操作符的操作数,是上下文决定的,(a+b)作为整体位与移位操作符的左边也是上下文决定的,(a+b)>>1作为整体是=操作符的右操作数,也是上下文决定的,因此answer(因为=),a,b(因为三层上下文嵌套)都被加入上下文环境中,这三个变量的位宽都是一样的,所以他们三个在运算前不会有拓展。因此首先执行a+b,根据规则,结果为16位,进位被丢失,然后再右移一位,最高位补0,最后赋值给同为16位的answer。很多时候方法很简单。改成a+b+17'b0;原创 2023-01-27 22:03:25 · 9882 阅读 · 82 评论 -
Verilog基础:表达式符号的确定
如果所有操作数有符号,结果才是有符号的。有两个系统函数就是为了调整表达式符号,分别是$signed和$unsigned,它们的返回值就是被转换符号后的数值。否则必须在基数前声明s标志才表示这个常数为有符号的,如3'd4是无符号数,3'sd4是有符号数。拼接操作符的结果是无符号的,不管操作数是否有符号,即使是只有一个有符号操作数也是如此。域选的结果是无符号数,不管域选操作数是否有符号,即使域选的结果是整个向量。比较操作符的结果是无符号的,不管操作数是否有符号。位选的结果是无符号数,不管位选操作数是否有符号。原创 2023-02-01 21:46:53 · 695 阅读 · 0 评论