一.数据类型

二值逻辑变量

bit

  • 不赋值的时候,变量初始默认为0
  • x或z的值会转变为0
  • bit vector--bit矢量
  1. bit [msb,lsb] variable_name = [initial_value]
  • 位宽:最高位为MSB,最低位为LSB
  • 不加任何描述,默认为unsigned,无符号数;表示有符号数需要加signed进行描述
  • 二值逻辑方便编译器的优化,效率更高,性能更好;但是不支持X和Z状态,不适用于RTL设计

    建立自己的仿真目录
  1. sim -- 仿真目录,放Makefile文件
  2. RTL -- 放RTL代码
  3. TB -- 放testbench
  • 使用tb文件进行仿真
  1. module tb_test;
  2. //定义变量
  3. bit [3:0] a;
  4. bit [4:0] b;
  5. initial begin
  6. a = 4'b0;
  7. b = -10;
  8. $display("a = %b",a);
  9. $display("b = %b",b); // 10110 就是-10的补码
  10. end
  11. endmodule
  • begin end之间就是代码块
  • $display()就类似于print()函数
  • 使用Makefile进行测试

    Makefile文件
  1. PLATFORM = LINUX64
  2. FLIST := ../tb/tb_test.v
  3. run:
  4. vcs -sverilog $(FLIST) -debug_all -P ${NOVAS_HOME}/share/PLI/VCS/LINUX64/novas.tab ${NOVAS_HOME}/share/PLI/VCS/LINUX64/pli.a -R -kdb -lca
  5. wave:
  6. verdi -simflow -elab simv.daidir/kdb.elab++ -ssf sim.fsdb
  7. clean:
  8. rm csrc novas_dump.log sim.fsdb simv simv.daidir ucli.key verdi_config_file novas.conf novas.rc verdiLog -rf

通过make run进行仿真

byte\shortint\int\longint

  • byte 8bit
  • shortint 16bit
  • int 32bit
  • longint 64bit
  1. byte/shortint/int/longint variable_name = initial_value;
  • 默认都是有符号数,十进制数
  • 在前端设计中,这些数据类型是很少用到的
  1. shortint temp = 256;
  2. int sample,ref_data = -9876;
  3. longint a,b;
  4. longint unsigned testdata;

real & shortreal

  • real 等于C语言中的double,64bit
  • shortreal等于C语言中的float,32bit
  • 有符号数
  • 在验证覆盖率的时候会用到
  1. real/shortreal variable_name = initial_value
  2. real alpha = 100.0,coverage_result;
  3. coverage_result = $get_coverage();
  4. if(coverage_result = 100.0)...

四值逻辑变量

  • 四值逻辑:0,1,x,z
  • 如果不声明数值,变量的初始值为x;在进行设计的时候要避免x态传递

reg & logic

  • 四值逻辑在verilog中使用reg
  1. reg [MSB:LSB] variable_name = initial_value;
  • 在SV中使用logic变量
  1. logic [MSB.LSB] variable_name = initial_value;
  • reg和logic如果不用signed修饰,默认都是无符号数
  • logic继承了reg所有的特性,但是logic可以进行连续赋值,并且只有一个驱动;如果定义了一个reg变量,是不能用assign对其进行赋值的,但是logic变量可以用assign进行赋值
  • SV中:logic相当于reg和只有一个驱动的wire
  1. module tb_test;
  2. wire [3:0] b;
  3. assign b = din_c;
  4. assign b = din_d; //多个变量和b连接,多驱动,前提是cd具有推拉结构,OC,OD门
  5. wire [3:0] e;
  6. assign e = din_c; //单驱动
  7. endmodule

integer & time

  • integer,32bit有符号数
  • time,64bit无符号数
  1. integer a = -100,b;
  2. time current_time;
  3. b = -a;
  4. current_time = $time;// $time内置函数,返回仿真时间
  5. if(current_time>100ms).....

枚举类型

将所有的情况列举出来,在状态机中使用的比较多,比如FSM有限状态机

  • 默认的数据类型是int
  • 初始化值是0
  • 可以使用枚举变量.name,显示枚举字符
  1. enum [data_type] {named constants} enum_var1,enum_var2....;
  1. module tb_test;
  2. enum bit[2:0] {IDLE=3'b001,TEST=3'b010,START=3'b100} st; //声明枚举类
  3. initial begin
  4. st = START;
  5. $display("st=%3b,name=%s",st,st.name); //st = 100,name=START
  6. $finish;
  7. end
  8. endmodule
  • 使用typedef定义枚举类,方便例化
  1. typedef enum [data_type] {named constants} enumtype;
  2. typedef enum bit[2:0] {IDLE=3'b001,TEST=3'b010,START=3'b100} state; //定义枚举类
  3. state st; //例化一个枚举
  4. initial begin
  5. st = START;
  6. $display("st=%3b,name=%s",st,st.name); //st = 100,name=START
  7. $finish;
  8. end
  • 不使用枚举类型还可以使用parameter
  1. parameter variable_name = initial_value;

固定数组

  1. type(数据类型 bit reg logic..) [位宽] array_name [size] = initial value;
  • 超过边界的写操作将被忽略
  • 超过边界的读操作:2值逻辑返回0,四值逻辑返回x
  • 支持多维数组
  • size--就是数组长度,index从0开始
  1. integer number[5]; //定义一个长度为5的数组,不给初值
  2. int b[2] = {3,7};
  3. int c[2][3] = {{3,7,1},{5,1,9}}; //定义二维数组
  4. byte d[7]][2] = {default:-1} ; 将所有元素的值都设置默认-1
  5. bit [31:0] a[2][3] = c; //数组可以通过赋值的方式进行复制
  6. for(int i = 0;i<$dimensions(a);)
  7. $display($size(a,i+1);) // 2,3,32
  • $dimensions(数组)--返回数组的维数
  • $size(数组,数组维数)--返回给定数组维数数组元素的个数
  1. module tb_test;
  2. logic [3:0] arr[3]; //定义长度为3的一维数组,每个元素为三位二进制数
  3. logic [3:0] arr2[3][3]; //定义二维数组
  4. initial begin
  5. arr[0] = 4'd2;
  6. end
  7. endmodule

二.操作符

语法规则

  • verilog和system verilog一样,都是大小写敏感的
  • 注释 // /**/
  • 数制格式
  1. <size>'<base><number>
  • base-b表示2进制 ,d表示10进制,h表示16进制数
  • size是将数值转化为二进制数的时候的二进制位宽
  1. 32'h_beef_cafe

操作符

  • 一般在写除法的时候,是需要设计特定的算法进行计算的,硬件当中实现除法比较麻烦
  • 自增和自减用在for循环中使用的比较多
  • 逻辑运算&& || !
  • 逻辑等于,不等于 == !==
  • 逻辑与或非,在运算的时候需要参与运算的位数应该都是一位的

    左移和右移运算
  1. module tb_test
  2. logic [3:0] a;
  3. initial begin
  4. a = 4'b0011;
  5. d = $signed(4'b0011); //转化为有符号数
  6. b = a << 2;
  7. c = d >>> 2;
  8. $display("b = %4b",b); //左移低位补零,1100
  9. $display("c = %4b",c); //右移,逻辑运算右移>>,高位补0,算术右移>>>,高位补符号位 c = 1111
  10. end
  11. endmodule
  • 按位与或
  1. module tb_test.v
  2. logic [3:0] a;
  3. logic [3:0] b;
  4. initial begin
  5. a = 4'b0011;
  6. b = 4'b0011 & 4b'1100;
  7. $display("b = %4b",b);
  8. $finish;
  9. end
  10. endmodule
  • 缩减运算符,单目运算符,第一位与下一位进行运算,最后输出一位
  • 三目运算符
  1. module tb_test.v
  2. logic [3:0] a;
  3. logic [3:0] b;
  4. logic sel;
  5. logic [3:0] mux;
  6. initial begin
  7. mux = sel ? a : b;
  8. $finish;
  9. end
  10. endmodule
  • {a,b} -- 将ab两个数连接在一起,
  1. a = 4b'1100;
  2. b = 4b'0011;
  3. c = {a,b}; // 1100_0011
  • 逻辑比较运算符

  • == != 遇到x和z,就会返回x

  • === !=== 会将0 1 x z都进行匹配



  • 通配比较符

匹配等==?和不匹配等!=?,按位比较,把x和z值当作匹配值,仅仅把右侧操作数中的z和x当作屏蔽信号

可以理解为,右边能够匹配上左边就返回真,xz可以取任意值0或1

  1. a=4'b1111;
  2. b=4'b11xz
  3. a==?b//数字相等,只要x和z能通配到1就可以是匹配等,返回逻辑值为1'b1,真
  4. A = 010z;
  5. B = 0101;
  6. A ==? B; //右边匹配不上左边 x
  7. B ==? A; // z=1的时候,右边===左边 1

赋值语句

  • -= += *= /= %=
  • 在assign中使用复合赋值运算,会形成组合逻辑环comb loop

三.控制语句

自增和自减运算符

经常用在for循环中

  1. for(int i = 0 ; i < 3; i++)begin
  2. .....
  3. end
  4. i = 1;
  5. j = i++; // j = 1
  6. j = ++1; // j = 2
  7. j = i--; // j = 1
  8. j = --i; // j = 0

在阻塞赋值总使用自增自减运算符,会造成竞争与冒险

  1. module tb_test;
  2. integer i,j;
  3. initial begin
  4. i = 0;
  5. j = 0
  6. while(i++<5) begin //先判断再加一,当i=5时,判断不满足,还要再加1,最后i = 6
  7. end
  8. while(++j<5) begin // 先加1,再判断,j=5
  9. end
  10. end
  11. endmodule

自定义类型

使用typedef为一个数据类型创建符号

  1. typedef logic [31:0] vec;
  2. vec a; // 创建32位a变量
  3. vec b; // 创建32位b变量

在一些变量定义比较长的时候进行使用

数据类型转换

  1. type'(value或variable)
  1. logic signed [31:0] a;
  2. logic [31:0] b;
  3. logic [63:0] c;
  4. assign c = a*b; //error,有符号数*无符号数出错,需要进行数据类型转换
  5. assgin c = unsigned(a)*b;
  1. bit [7:0] playload[]; //不给数组长度就是定义了一个动态数组
  2. int temp = $random; // 生成一个随机数
  3. playload = new [(temp%3)+2]; //实例化数组并指定长度
  4. playload = new [(uint'(temp)%3)+2];
  5. playload = new [(unsigned'(temp)%3)+2];

顺序控制



1.for循环

sv中循环遍历可以在for语句中定义,verilog中只能定义在外部

for循环中声明的i和外部声明的i是不相同的,互不影响

  1. for(int i;i<3;i++) begin
  2. end
  1. while
  1. while() begin
  2. end
  1. continue/break/return
  • return 结束函数和task;用于循环,停止循环
  • continue 用于循环语句,结束本次循环,执行下次循环
  • break 用于循环语句,跳出循环
  1. do ... while
  • while循环的时候,不一定会执行
  • do..while至少会执行一次
  1. do begin
  2. ...
  3. end while(条件)

5.case

先计算表达式值,将case中的值与表达式的值进行匹配,匹配成功执行语句

  • 匹配是从上到下匹配的
  1. case(expr)
  2. value1: xxxxxx
  3. value2: xxxxxx
  4. ...
  5. default xxxx
  6. endcase

6.casez或casex

  • casez 不关心z
  • 忽略对应位上的z
  1. sel = 4'b1100;
  2. casez(sel)
  3. 4b'1101:data = 4'b01;
  4. 4b'zz00:data = 4'b00; //casez会匹配zz00 casez就不关心value中的z位置对应的值
  5. default data = 4'b0011;
  6. endcase
  • casex忽略对应位置出现的x和z
  1. @ & wait
  • @ 等待时间发生才执行后面的程序,可以是信号变量,上升沿,下降沿,事件变量
  1. always@(posedge Clk) begin
  2. ...
  3. end
  • wait(expr) begin...end 是不可综合的
  • 延迟信息 #5 5个时间单位,单位体现在timescale = 1np/100ps

07-verilog & sytem verilog的更多相关文章

  1. Verilog笔记——Verilog数字系统设计(第二版)夏宇闻

    本片记录Verilog学习笔记,主要是和以往用的C语言的不同之处,以例子.代码的形式记录.学习以<Verilog数字系统设计>(第二版)为参考资料,援助作者夏宇闻. 1. C语言和Veri ...

  2. 【Verilog】verilog实现奇数次分频

    实现占空比为50%的N倍奇数分频:首先进行上升沿触发进行模N计数,计数到某一个值时进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%的奇数n分频时钟.再者 同时进行下降沿触发的 ...

  3. system verilog中的类型转换(type casting)、位宽转换(size casting)和符号转换(sign casting)

    类型转换 verilog中,任何类型的任何数值都用来给任何类型赋值.verilog使用赋值语句自动将一种类型的数值转换为另一种类型. 例如,当一个wire类型赋值给一个reg类型的变量时,wire类型 ...

  4. Verilog Tips and Interview Questions

    Verilog Interiew Quetions Collection :  What is the difference between $display and $monitor and $wr ...

  5. verilog 介绍

    Verilog HDL Verilog HDL是在C语言的基础上发展起来的一种硬件描述语言,语法较自由.VHDL和Verilog HDL两者相比,VHDL的书写规则比Verilog HDL烦琐一些,但 ...

  6. verilog语法实例学习(4)

    Verilog模块 Verilog中代码描述的电路叫模块,模块具有以下的结构: module module_name[ (portname {, portname})]; //端口列表 [parame ...

  7. verilog FAQ(zz)

    1. What is the race condition in verilog? Ans :The situation when two expressions are allowed to exe ...

  8. 全平台轻量开源verilog仿真工具iverilog+GTKWave使用教程

    前言 如果你只是想检查Verilog文件的语法是否有错误,然后进行一些基本的时序仿真,那么Icarus Verilog 就是一个不错的选择.相比于各大FPGA厂商的IDE几个G的大小,Icarus V ...

  9. 【FPGA学习】根据datasheet编写Verilog驱动(PCF8574 IO扩展板练习)

    在之间的博客中已经讲了如何阅读一本datasheet并编写Verilog驱动代码,而在这篇博客中就加以应用,为PCF8574 IO扩展板编写驱动并观察效果,至于为什么选择这个,一方面是因为这个芯片功能 ...

  10. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十四:储存模块

    实验十四比起动手笔者更加注重原理,因为实验十四要讨论的东西,不是其它而是低级建模II之一的模块类,即储存模块.接触顺序语言之际,“储存”不禁让人联想到变量或者数组,结果它们好比数据的暂存空间. . i ...

随机推荐

  1. .NET 8上进行PDF合并

    前言:在.NET 8中使用itext7需安装 itext7 和 itext7.bouncy-castle-fips-adapter 两个Nuget包,或者使用Aspose.PDF.PdfSharpCo ...

  2. 复习:Java基础-泛型方法

    泛型 大家都很熟悉了 泛型方法呢 可能很多小伙伴都有混淆,今天来稍微复习一下 泛型方法(普通方法) public class Test<T> { public T f(T c) { //注 ...

  3. CentOS安装openGauss2.0.1

    CentOS安装openGauss2.0.1 OpenGauss是一款开源关系型数据库管理系统,采用木兰宽松许可证v2发行.openGauss内核源自PostgreSQL,深度融合华为在数据库领域多年 ...

  4. Ubuntu20.04 安装shutter

    1 sudo add-apt-repository ppa:linuxuprising/shutter 2 3 sudo apt install shutter 4 5 卸载 6 sudo apt-g ...

  5. 2023-08-16:用go语言如何解决进击的骑士算法问题呢?

    2023-08-16:用go写算法.一个坐标可以从 -infinity 延伸到 +infinity 的 无限大的 棋盘上, 你的 骑士 驻扎在坐标为 [0, 0] 的方格里. 骑士的走法和中国象棋中的 ...

  6. vue常用函数

     this.$router.back();  //回退上一页面

  7. vue获取公网ip

    <template> <div> <div>Your Public IP: {{publicIP}}</div> </div> </t ...

  8. Cesium渲染一帧中用到的图形技术

    译者注:本文翻译自Cesium官方博文<Graphics Tech in Cesium - Rendering a Frame>,May 14, 2015 by Patrick Cozzi ...

  9. 【华为云技术分享】LiteOS无法直接烧录或者烧录失败解决方法--ST-Link

    前提条件: 程序编译成功,并且电脑上已经安装ST-Link驱动,你使用的仿真器也是ST-Link. 上图黑色的是J-Link,下图紫色的是ST-Link,本教程适用于ST-Link,如果是J-Link ...

  10. 如何利用动态配置中心在JavaAgent中实现微服务的多样化治理

    本文分享自华为云社区<如何利用动态配置中心在JavaAgent中实现微服务的多样化治理>,作者:华为云开源 . 一.前言 随着JavaAgent在微服务治理方面的广泛应用和发展,我们可以在 ...