
SystemVerilog
文章平均质量分 59
SystemVerilog基础
傻童:CPU
业精于勤,荒于嬉;行成于思,毁于随。
展开
-
代码覆盖率
代码覆盖率是衡量验证进展的最简易的方式。它的作用是检查代码是否冗余,设计要点是否遍历,被检测的对象是RTL代码,而代码覆盖率的检测一般由工具自动生成的,不需要自定义收集条件。如果只是为了验证分支覆盖率,以上的两种情况就足够了,因为if语句中两种分支条件都有了,但是对于第一条分支中的只有在test1()为false情况下的BUG,这里并没有覆盖到。而在条件覆盖率下,还需要验证test1()为false且test2()为true这种情况,只有这三种情况都验证到了,才算是满足了条件覆盖率。...原创 2022-07-24 11:21:17 · 7985 阅读 · 0 评论 -
PID笔记
在t时刻:PID的控制规律为:假设是规定为直流电机调速的。输入量rin(t)为电机转速预定值(转/min)。输出量rout(t)为电机转速实际值(转/min)。偏差量为预定值和实际值之差(转/min)。执行器为直流电机。传感器为光电码盘(10线)。为了得到实际的转速。直流电机采用PWM调速转速,单位为转/min表示。问题一:通过PID环节后的u(t)是什么值?问题二:控制执行器(直流电机)转动转速应该为电压值(也就是PWM占空比)?问题三:u(t)与PWM之间存在怎样的联系?PID控制其实是原创 2022-06-07 18:35:40 · 601 阅读 · 0 评论 -
基于断言的验证
断言的概念十分简单。只要在程序中声明,我们相作言某事情必定为真,若不为真,则在屏幕上打印错误信息即可。在 SystemVerilog语言中,断言可以用立即(immediate)和并发(concurrent)两种不同形式的断言来表示。立即断言十分简洁,可以用if、else等语句表示。而并发断言的功能十分强大,所以本节用大部分篇帽福讲解如何编写并发断言。在 always过程块中可以把这个事实声明为立即断言(该立目即断言相当于一个always_comb过程块,但是为了避免概念混淆,我们只在可综合的RTL模块中使用原创 2022-06-06 14:08:02 · 634 阅读 · 0 评论 -
面向对象的编程
面向对象编程(OOP)原本属于软件开发方法学范畴,似乎与SystemVerilog这一类硬件描述语言没有任何关系。在传统的编程语言,例如C和FORTRAN中,程序根据数据结构进行操作。在 SystemVerilog语言的过程块(例如initial和always块)中,程序的运行与传统的编程语言十分类似。**所谓面向对象编程,其实就是把程序内部的执行细节放到程序外部进行描述;把数据结构和函数对数据结构的操作置于多个类的声明中,然后实例引用这些类,并把它们转变成具体的对象,再组装成可以执行的程序。**虽然Sys原创 2022-06-06 13:08:26 · 241 阅读 · 0 评论 -
时序构成的测试平台
在任何类型的设计中,最重要的信号是时钟信号。把信号电平按照规定的时间间隔反相,就可以产生时钟信号,这是最简单时钟信号发生器。任何信号的默认值为“x”。若只是把某个信号按照规定的时间间隔反相,将把“x”值反相。下面的代码不能产生时钟信号的原因就在于此;按照这个代码,时钟信号将永远为不定态“x”。发生错误的原因是忘记设置时钟信号的初始值。只要添加设置时钟初始值语句,就可以解决这个问题:**最好把每个信号初始值的设置和发生编写在一个过程块中。**举例说明如下:下面的例子描述了时钟频率和占空比都是参数的时钟原创 2022-06-05 17:04:04 · 194 阅读 · 0 评论 -
使用Systemverilog描述状态机
系统的状态必须保存在内部寄存器中。在SystemVerilog语言中,状态可以用枚举类型(enumerated type)表示。这种类型的可能值是状态名,而变量名列在一系列可能值的后面。例如:在下面的代码中,有两个过程块。每个过程块都标有自己的名字。第一个标有SEO的过程块描述了一个状态机。该过程块等待时钟的正跳变沿的到来,或者等待复位信号的负跳变沿的到来。首先测试的是异步复位信号,如果复位信号的负跳变沿到来,则默认值G被赋值给状态变量state。否则,跳转到case语句分支,根据当前的状态值进人不同的分原创 2022-06-05 15:51:01 · 886 阅读 · 0 评论 -
触 发 器
由正跳变沿触发的D触发器的最简单的SystemVerilog模型如下所示:因为这是时序逻辑,所以必须用非阻塞赋值。同样,负跳变沿触发的触发器可以通过检测逻辑电平从1跳变到0来建立模型。这两个输入应该只用于触发器的初始化。在系统正常运行期间,用R和S信号来设置触发器的状态是一个坏习惯,必须改正。这样做是因为在同步系统中,触发器的状态改变只允许由时钟的跳变沿触发。由于置位或复位输人信号是异步的,因此不能确保触发器输出的改变发生在特定时刻。这会引起各种时序问题。总而言之,在设计中必须保持严格的同步,或者遵循结原创 2022-06-04 22:11:28 · 585 阅读 · 0 评论 -
组合逻辑块的测试平台
测试平台是不需要综合的,因此SystemVerilog的所有语法都可以用来编写测试平台。测试平台的模块不需要声明输入和输出,测试平台包括了被测试对象、产生测试激励的信号源及观察或记录被测对象输出的机制。测试平台通常实现两大功能:1)产生被测模块所需的输入激励:2)检查被测模块的输出结果。在实例引用加法器adder时,用到一个参数(N)和一个将激励信号与加法器连接的端口匹配符(*)。只有当测试平台中的线网和变量名与被实例引用的模块的端口名完全一致时,才允许使用这种简化的端口连接方法。请注意,时间是相对的原创 2022-06-04 21:06:36 · 206 阅读 · 0 评论 -
使用SystemVerilog门模型描述的组合逻辑
组合逻辑是无状态的,换言之,输人的变化立即反映在输出的改变上。SystemVerilog的基本构造单元是模块(module)。模块描述从关键字module开始,接着是模块名和括号中的输入和输出列表。模块以关键字endmodule结束 请注意,在模块的第一句后有分 号“;”,但是在关键字endmodule后面没有分号。在上述例子中,该模型只有一条声明语句。用关键字 assign来表明所谓的连续赋值 (continuous assignment)语句(这将在后面解释)。x和y 的按位相与得到的值被赋给z。原创 2022-06-04 17:00:52 · 288 阅读 · 0 评论 -
格雷码与二进制的转换
格雷码转二进制是从左边第二位起,将每位与左边一位二进制码的值异或,作为该位二进制码后的值(最左边一位依然不变)。以其中一个为例:格雷码111->二进制101第一步:最左边不变->1**。得出二进制第一位为1第二步:从左往右.第三步:异或->10*。1^1得出二进制第二位为0第四步:将上一步的结果(二进制位)与格雷码异或->101。0^1得出二进制第三位为1从最右边一位起,依次将每一位与左边一位异或(XOR),作为对应格雷码该位的值,最左边一位不变。以其中一个为例:二进制101->格雷码111原创 2022-06-04 11:28:42 · 26403 阅读 · 1 评论 -
布尔代数值
数字系统使用二值代数。其变量可以取由:1)接通/断开;2)真/假;3)1/0表示的两值之一。1)NOT(非)2)AND(与)3)OR(或)4)IMPLIES(蕴涵)5)EQUIVALENCE(同或)上面表达式中的符号“+”表示“或”;符号“·”表示“与”;而横杠,例如“~A”则表示“A的非”。应用对偶律可以把左边那一列等式转变为右边的那列等式。所谓对偶律是指如果把每个与门变成或门,每个或门变成与门,每个1变成0,每个0变成1,则表达式的值保持不变。...原创 2022-06-04 10:23:06 · 201 阅读 · 0 评论 -
COMS技术
n型MOS(NMOS)三极管的结构如图所示,该图不是按照实际比例绘制的。三极管的衬底是被掺杂后成为p型半导体材料的硅晶片。NMOS衬底的厚度远比其他三极管要厚。在每个三极管上有两个区域,被掺入大量的杂质,成为n型半导体区域。这两个区域分别形成了三极管的源极和漏极。实际上,源极和漏极可以互换,但是不管如何互换,源极到漏极的电压通常总是正的。在源极和漏极上都有各自的金属连接点。多晶硅(polysilicon)栅极与三极管的其他区域之间用二氧化硅绝缘层隔离。原先,栅极也有金属连接点;MOS的名称也是因金属氧化半导原创 2022-06-03 22:10:24 · 640 阅读 · 0 评论 -
SystemVerilog笔记
SystemVerilog笔记使用($isunknown)操作符,可以在表达式的任意位出现X或Z时返回1。$size函数返回数组的宽度原创 2022-04-11 09:47:06 · 3288 阅读 · 0 评论 -
命名的结束语句
命名的结束语句1、命名的模块结尾SystemVerilog允许关键字endmoule后指定模块的名字endmoule:<module_name>endmodule后指定的名称必须与匹配的模块名称一致2、命名的代码块结尾SystemVerilog还允许对其他命名的代码块指定结尾名称。这包括以下关键字:interface…endinterface、task…endtask、function…endfunciton和begin…end以及其他主要用于测试平台的命名代码。3、嵌套(局部)原创 2022-03-10 09:35:20 · 864 阅读 · 0 评论 -
层次化设计
层次化设计1、模块原型外部的模块声明SystemVerilog允许用户为被实例化的模块指定一个原型,这就简化了编译过程。原型的定义使用关键字extern,extern之后是模块及其端口是声明。//使用Verilog-1995代码风格的原型entern module counter(cnt,d,clock,resetN)//使用Verilog-1995代码风格的原型extern module counter#(paramter N=15) (output logic[N:0]原创 2022-02-14 18:19:56 · 632 阅读 · 0 评论 -
在FSM模型中使用两态数据类型
在FSM模型中使用两态数据类型1、使用两态类型和枚举类型对FSM复位在仿真刚开始时,四态数据类型的值是逻辑X。类似有限状态机这样的模型中,四态变量的X逻辑值可以用来表示模型还没有复位,或复位逻辑的建模不正确。仿真刚开始时,两态数据类型的缺省值是0而不是X。因为复位操作通常是将大部分变量清0,所以这样一来即使复位逻辑有缺陷,模型好像仍然是被复位了。仿真开始时,枚举类型使用枚举类型的基类值作为缺省值。如果状态变量用默认基类和标签值定义并且复位操作也是将枚举值置为表中的第一个值,那么就会出现和两态变量类似原创 2022-02-14 17:40:58 · 386 阅读 · 0 评论 -
有限状态机建模
有限状态机建模1、使用枚举类型建立状态机模型枚举类型有固定的数值枚举类型提供了一种定义一个具有有限合法数值集合的变量的方法。数值是用标签而不是数字逻辑值表示的。枚举类型支持抽象FSM类型枚举类型支持更高抽象层次的建模,并且能描述精确的、可综合的硬件行为。使用了枚举变量后,变量State和Next的值只可能在其枚举列表中。在状态逻辑中的case语句前的修饰符unique有助于保证case语句能覆盖量State和Next所有可能值(unique case)//使用枚举类型建模的有限状态机modu原创 2022-02-14 15:23:44 · 1013 阅读 · 0 评论 -
改进的if...else判断语句
改进的if…else判断语句SystemVerilog的判断修饰符unique和priority可以和if…else一起使用。使用这些修饰符不仅可以减少此类判断语句的不确定性,还可以在建模早期发现潜在的设计错误。1、unique if…else判断语句unique if…else可以并行求值修饰符unique表示条件排列的顺序并不重要。软件工具会将推断出的判断顺序优先级优化掉。logic[2:0] sel;always_comb begin unique if(sel==3'b001) mu原创 2022-02-13 20:24:25 · 810 阅读 · 0 评论 -
priority case语句
priority case语句一个priority case可能具有多个条件选项匹配priority case语句指定:至少有一个条件选项的值与条件表达式匹配如果有多个条件选项的值与条件表达式匹配,必须执行第一个匹配分支修饰符priority表示设计者认为两个或多个条件选择表达式可以同时为真,并且条件选项的顺序非常重要。//设计者指定了中断请求信号译码顺序的优先级,//irq0具有最高优先级always_comb priority case(1'b1) irq0:irq=4'b0原创 2022-02-13 17:08:04 · 423 阅读 · 0 评论 -
改进的case语句
改进的case语句SystemVerilog为case、casex和casez的判断提供了专门的unique和priority修饰符。这些修饰需放在关键字case、casex和casez前面。unique case(<case_expression>) ...//条件选项endcasepriority case(<case_expression>) ...//条件选项endcase1、unique case条件判断unique case语句指定只有一个条件选原创 2022-02-13 16:52:41 · 1096 阅读 · 0 评论 -
改进的块名
改进的块名代码中可包括多个嵌套begin…end块命名的end可以和命名的begin配对如果想在一个块的结尾指明它的名称,可以在关键字end后面加上:<名称>。在冒号的前后允许有空格,但不是必须的。begin:<块名>...end:<块名>这个跟着end后面的快名称是可选的,但它必须和相对应的begin后的名称一致。如果两者不同,系统会报告错误。8、语句标号命名用来识别一组语句除了命名语句块,SystemVerilog还可以在任意过程语句前指定一个标原创 2022-02-12 20:13:17 · 496 阅读 · 0 评论 -
底部检测的do...while循环
底部检测的do…while循环1、while循环可能从未执行while循环有可能根本没有执行过。当执行流首次执行到循环的开头,控制值就为假的时候就会发生这种情况。为了保证循环的每个输出都与循环的输入变量保持一致,使用这种在开头检测的while循环需要在循环之前增加代码。always_combbegin if(addr < 128 || addr >255) begin done = 0; outofBound = 1; out = mem[128]; end els原创 2022-02-11 21:44:56 · 405 阅读 · 0 评论 -
改进的for循环
改进的for循环声明局部循环变量SystemVerilog简化了声明用于for循环的局部变量的方法。SystemVerilog可以在for循环内部声明循环变量。这样就不需要在模块级定义多个变量,也不用在命名的begin…end块中定义局部变量了。module chip(...);//SystemVerilog风格的循环 ... always_ff@(posedge clock) begin for(bit[4:0] i=0; i<=15;i++) .... end always原创 2022-02-10 21:36:04 · 439 阅读 · 0 评论 -
操作数改进
操作数改进1、两态和四态类型数据的运算全两态类型的运算使用Verilog运算法则Verilog对大多数操作数类型的混合运算都制定了相应规则。SystemVerilog包含了Verilog没有涉及的两态类型数据的运算,从而对这些规则进行了扩展。对SystemVerilog新类型的运算按照相同的Verilog规则进行。这就意味着对结果的每一位,大部分运算会返回0、1或X。当对两态类型进行运算时,一般很少会遇到X结果。不过对两态类型的一些运算会产生X,如除以0产生的错误。2、类型强制转换SystemV原创 2022-02-10 20:52:26 · 615 阅读 · 0 评论 -
设置成员操作符--inside
设置成员操作符–insideSystemVerilog增加了一个检测是否集合中–员的操作符,这个操作符的关键字是inside。logic [2:0] a;if(a inside{3'b001,3'b010,3'b100})//等价if((a==3'b001)||(a==3'b010)||(a==3'b100))...使用inside操作符可以方便的比较一个数值和多个可能值之间的关系。用inside操作符,需要和第一个值进行比较的数值集合可以是其他信号。if(data inside{bus1原创 2022-02-10 20:09:27 · 1502 阅读 · 0 评论 -
有无关通配符的相等操作符
有无关通配符的相等操作符== 逻辑相等操作符=== 条件相等操作SystemVerilog通配符相等操作符允许屏蔽某些位SystemVerilog还增加了两个新的比较操作符:== ?和!=?。这两个操作符允许在比较中屏蔽无关位。操作符 ==?,又称通配相等操作符,对两个操作数进行按位比较,这与逻辑相等操作符 == 的使用类似。但是在通配符==?的使用中,右边操作数中的一位逻辑X或逻辑Z都被看做是一个通配符,而这个通配符可以和另一个操作数中相应位的任何数值相匹配。如果两个操作数的原创 2022-02-10 16:46:50 · 693 阅读 · 0 评论 -
赋值操作符
赋值操作符+=和其他赋值操作符out += in;//将out和in相加并将结果赋值给out//out = out + in;注意:这些操作符都是阻塞赋值packdage definitions; typedef enum logic[2:0] {ADD,SUB,MULT,DIV,SL.SR} opcode_t; typedef enum logic{UNSIGNED,SIGNED}operand_type_t; typedef union packed{ logic[23:0]原创 2022-02-10 14:19:29 · 566 阅读 · 0 评论 -
递增和递减操作符
递增和递减操作符++和- -操作符for(i = 0;i <= 31; i++)begin ...end先加与后加通常原则是,对组合逻辑使用阻塞赋值,而对时序逻辑赋值使用非阻塞赋值。注意:++和--操作符是阻塞赋值i++;//使用阻塞赋值对i进行递增i=i+1;//使用阻塞赋值对i进行递增++和- -在时序逻辑中可能产生竞争先加和先减不能解决两条并发语句间的竞争问题。先加/减或后加/减只影响该语句内对变量的读取和修改的顺序,而不影响并发语句间的读取和修改变量的顺序。在需原创 2022-02-10 13:44:44 · 432 阅读 · 0 评论 -
对任务和函数的改进
对任务和函数的改进1、任务和函数的隐式语句组SystemVerilog会推断出begin…endSystemVerilog简化了任务和函数的定义,有多条语句时不在需要begin …end对多条语句进行打包。打包省略之后,任务或函数中的语句将会顺序执行,就像仍然在begin…end中一样。function states_t NextState(State_t State); NextState = State;//默认次态 case(State) WAITE:if(start) NextSta原创 2022-02-10 12:47:56 · 472 阅读 · 0 评论 -
时序逻辑过程块
时序逻辑过程块always_ff描述时序逻辑always_ff专用过程块表示设计的意图是描述可综合的时序逻辑。always_ff@(posedge clock,negedge resetN) if(!resetN) q <=0; else q <= d;always_ff过程块的敏感表必须明确列出。这样就可以根据敏感表的内容,确定时序逻辑的置位/复位是同步还是异步的。工具会验证always_ff的内容表达的时序逻辑always_ff会限制生成可综合敏感表always_ff过程原创 2022-02-09 09:36:26 · 431 阅读 · 0 评论 -
锁存逻辑过程块
锁存逻辑过程块always_latch描述锁存逻辑always_latch过程块表示过程块描述的是基于锁存器的逻辑。和always_comb一样,always_latch的敏感表示推断出来的。always_latch if(enable) q <= d;always_latch与always_comb语义相同always_latch过程的语义规则与always_comb一样。两种过程快推断敏感表的规则也是一样的。在always_latch中赋值的变量不能再在其他任何过程块赋值。同样,为了原创 2022-02-09 09:22:34 · 723 阅读 · 0 评论 -
组合逻辑过程块
组合逻辑过程块always_comb代表组合逻辑always_comb过程块表示建立组合逻辑模型always_combif(!mode) y = a + b;else y = a - b;always_comb能推断出其敏感表与通用always过程块不同,always_comb块的后面不需要指明敏感表。软件工具已经知道设计的意图是建立一个组合逻辑模型,因此这个组合逻辑的敏感表可以是自动推断出来的。推断的敏感表包含了所有被过程块读取(所谓读取即信号出现在表达式右边或作为条件语句的条件表达式原创 2022-02-08 21:52:17 · 1123 阅读 · 0 评论 -
foreach数组循环结构体
foreach数组循环结构体foreach循环遍历任何维数的数组Systemverilog增加了foreach循环,它可用来对一维或多维数组中的元素进行迭代,而不必指定数组每个维度的宽度。foreach循环的自变量是数组名,它后面是方括号内用逗号隔开的循环变量列表。每个循环变量对应于数组的一个维度。int sum[1:8][1:3];foreach(sum(i,j)) sum[i][j] = i + j;//对数组初始化//最外层循环对i进行迭代,最内层循环对j进行迭代从循环变量到数组索引的原创 2022-02-08 15:49:24 · 901 阅读 · 0 评论 -
关于数组的内容
关于数组的内容Verilog数组声明的基本语法<data_type><vector_size><array_name><array_dimension>例如:reg[15:0] RAM [0:4095];//储存器数组原创 2022-02-08 12:49:30 · 722 阅读 · 0 评论 -
关于联合体的内容
关于联合体的内容联合体只储存一个值联合体只存储一个元素,但这个元素可以有多种表示方法,每种表示可以是不同的数据类型。联合体的声明语法类似于结构体,联合体的成员的引用也跟结构体一样。union{ int i; int unsigned u;}data;...data.i = -5;$display("data is %d",data.i);data.u = -5;$display("now data is %d",data.u);联合减少储存,提高性能尽管声明语法类似,但是联合体原创 2022-01-24 21:43:23 · 525 阅读 · 0 评论 -
关于结构体的内容
关于结构体的内容结构体使用类似于C语言的语法来定义结构体使用struct关键字声明。结构体内的成员可以是任何数据类型,包括用户自定义类型和其他的结构体类型。struct{ int a,b; //32位变量 opcode_t opcode;//用户定义类型 logic [23:0] adress;//24位变量 bit error; // 一位两态变量}Instruction_Word;结构体是变量和/或常量的集合结构体是一个名称下的变量和/或常量的集合。整个集合可以用结构体名进行引用。原创 2022-01-24 15:32:49 · 887 阅读 · 0 评论 -
用户自定义和枚举数据类型
用户自定义和枚举数据类型用户自定义1、typedef定义用户自定义类型SystemVerilog同C一样,使用typedef关键字来建立用户自定义类型。用户自定义类型允许使用现有的数据类型建立新的数据类型。新的数据类型定义后,可以声明这个类型的变量typedef int unsigned uint;...unint a,b;//unint类型的两个变量2、局部使用typedef用户自定义类型可以在局部定义,也可以在编译单元域进行外部定义。当一个用户自定义数据类型只用于设计的特定部分时,ty原创 2022-01-18 19:10:56 · 861 阅读 · 0 评论 -
变量初始化的确定性
变量初始化的确定性在最初的Verilog-1995标准中,变量不能像C语言一样,在声明的时候就能对变量进行初始化,而需要在另一个的initial过程块来设置变量的初值。integer i; //声明一个i变量integer j; //声明一个j 变量initial i = 5; //将i初始化为5initial j = i; //将j初始化为i的值...原创 2022-01-09 20:05:10 · 475 阅读 · 0 评论 -
静态和自动变量
静态和自动变量自动变量–也可以称为动态变量,主要是用来描述在测试程序、抽象系统级、交易级或总线功能模型中的验证程序。自动变量的另一个用途就是编写可重入的任务,当一个任务的前一次调用仍然在执行时,可以再次对其调用。自动变量也允许编写递归函数–函数调用其自身。含有自动变量的任务或者函数的每次调用,都建立新的变量储存空间,当访问结束后,空间被释放。function automatic int b_add (int lo,hi); int mid = (lo + hi + 1) >> 1; i原创 2021-12-23 20:18:09 · 1045 阅读 · 0 评论 -
数据类型规则的放宽
数据类型规则的放宽SystemVreilog放宽了使用变量的限制SystemVreilog放宽了变量的使用规则,大大简化了模型中数据类型的使用。在SystemVreilog中共,任何数据类型的变量都可以通过下列方式赋值,但只能采用其中的一种方式。(1)在任意的initial或always的过程中赋值(2)在单个always_comb,always_ff或always_latch过程块中赋值(3)通过单个的持续赋值语句赋值(4)通过单个模块或原语的output/inout端口驱动赋值大部分信号可原创 2021-12-22 20:01:07 · 340 阅读 · 0 评论