1、Verilog基础

1.1 特别的数值种类

x 或 X:未知
z 或 Z:高阻

(Z 常见于信号(input, reg)没有驱动时的逻辑结果。例如一个 pad 的 input 呈现高阻状态时,其逻辑值和上下拉的状态有关系。上拉则逻辑值为 1,下拉则为 0 。)

1.2、需要注意的整数数值表示方法

减号放在基数和数字之间是非法的,例如下面的表示方法是错误的:

4’d-2 //非法说明

1.3、强调Verilog 数据类型

2 种数据类型就是线网(wire)与寄存器(reg)

always块里赋值对象不能是wire型

1.4、算术操作符

无符号数乘法时,结果变量位宽应该为 2 个操作数位宽之和。

逻辑相等/不等操作符不能比较 x 或 z,当操作数包含一个 x 或 z,则结果为不确定值

全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1,即全等比较可比较 x 或 z。所以,全等比较的结果一定不包含 x。

1.5、Verilog 时延

在 Verilog 模型中,时延有具体的单位时间表述,并用 `timescale 编译指令将时间单位与实际时间相关联。

`timescale      time_unit / time_precision

time_unit 表示时间单位,time_precision 表示时间精度,它们均是由数字以及单位 s(秒),ms(毫秒),us(微妙),ns(纳秒),ps(皮秒)和 fs(飞秒)组成。时间精度可以和时间单位一样,但是时间精度大小不能超过时间单位大小。

由于在 Verilog 中没有默认的 timescale,如果没有指定 timescale,Verilog 模块就有会继承前面编译模块的 `timescale 参数。有可能导致设计出错。

如果一个设计中的多个模块都带有 `timescale 时,模拟器总是定位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小时延精度,时延单位并不受影响。

`timescale 的时间精度设置是会影响仿真时间的。时间精度越小,仿真时占用内存越多,实际使用的仿真时间就越长。所以如果没有必要,应尽量将时间精度设置的大一些。

1.6、编译指令

`default_nettype none,由于编译指令的存在,变量没定义就使用,系统会报Error,从而检查出书写错误

1.7、过程结构

assign 为关键词,任何已经声明 wire 变量的连续赋值语句都是以 assign 开头

一个模块中可以包含多个 initial 和 always 语句,但 2 种语句不能嵌套使用

这些语句在模块间并行执行,与其在模块的前后顺序没有关系。

但是 initial 语句或 always 语句内部可以理解为是顺序执行的(非阻塞赋值除外)

每个 initial 语句或 always 语句都会产生一个独立的控制流,执行时间都是从 0 时刻开始initial 语句从 0 时刻开始执行,只执行一次,多个 initial 块之间是相互独立的。

如果 initial 块内包含多个语句,需要使用关键字 begin 和 end 组成一个块语句

如果 initial 块内只有一条语句,关键字 begin 和 end 可使用也可不使用。

1.8、过程赋值

连续性赋值总是处于激活状态,任何操作数的改变都会影响表达式的结果过程赋值只有在语句执行的时候,才会起作用。这是连续性赋值与过程性赋值的区别。

Verilog 过程赋值包括 2 种语句:阻塞赋值与非阻塞赋值。阻塞赋值语句使用等号 = 作为赋值符非阻塞赋值语句使用小于等于号 <= 作为赋值符

非阻塞赋值属于并行执行语句,即下一条语句的执行和当前语句的执行是同时进行的,它不会阻塞位于同一个语句块中后面语句的执行。

实际 Verilog 代码设计时,切记**不要在一个过程结构中混合使用阻塞赋值与非阻塞赋值。**两种赋值方式混用时,时序不容易控制,很容易得到意外的结果。

在设计电路时,always 时序逻辑块中多用非阻塞赋值,always 组合逻辑块中多用阻塞赋值;在仿真电路时,initial 块中一般多用阻塞赋值。

1.9、时序控制

遇到常规延时时,需要等待一定时间,然后将计算结果赋值给目标信号。

遇到内嵌延时时,先将计算结果保存,然后等待一定的时间后赋值给目标信号。修饰常数时,延时效果一样

事件是指某一个 reg 或 wire 型变量发生了值的变化。事件控制用符号 @ 表示语句执行的条件是信号的值发生特定的变化

关键字 posedge 指信号发生边沿正向跳变(上升沿),negedge 指信号发生负向边沿跳变(下降沿),未指明跳变方向时,则 2 种情况的边沿变化都会触发相关事件。

任意一个发生变化都能够触发语句的执行时,Verilog 中使用"或"表达式来描述这种情况,用关键字 or 连接多个事件或信号。这些事件或信号组成的列表称为"敏感列表"。当然,or 也可以用逗号 , 来代替。更为简洁的写法是 @* 或 @(*),表示对语句块中的所有输入变量的变化都是敏感的。

Verilog 中还支持使用电平作为敏感信号来控制时序,即后面语句的执行需要等待某个条件为真。Verilog 中使用关键字 wait 来表示这种电平敏感情况

1.10、语句块

顺序块用关键字 begin 和 end 来表示。顺序块中每条语句的时延总是与其前面语句执行的时间相关。

并行块有关键字 fork 和 join 来表示

disable 可以终止命名块的执行,可以用来从循环中退出、处理错误等。

与 C 语言中 break 类似,但是 break 只能退出当前所在循环,而 disable 可以禁用设计中任何一个命名的块

需要说明的是,disable 在 always 或 forever 块中使用时只能退出当前回合,下一次语句还是会在 always 或 forever 中执行。因为 always 块和 forever 块是一直执行的,此时的 disable 有点类似 C 语言中的 continue 功能

1.11、循环语句

repeat 的功能是执行固定次数的循环,它不能像 while 循环那样用一个逻辑表达式来确定循环是否继续执行。repeat 循环的次数必须是一个常量、变量或信号。

如果循环次数是变量信号,则循环次数是开始执行 repeat 循环时变量信号的值。即便执行期间,循环次数代表的变量信号值发生了变化,repeat 执行次数也不会改变。

forever 语句表示永久循环,不包含任何条件表达式,一旦执行便无限的执行下去,系统函数 $finish 可退出 forever

1.12、过程连续赋值

与过程赋值不同的是,过程连续赋值的表达式能被连续的驱动到 wire 或 reg 型变量中,即过程连续赋值发生作用时,右端表达式中任意操作数的变化都会引起过程连续赋值语句的重新执行。

assign(过程赋值操作)与 deassign (取消过程赋值操作)表示第一类过程连续赋值语句。赋值对象只能是寄存器或寄存器组,而不能是 wire 型变量。

force (强制赋值操作)与 release(取消强制赋值)表示第二类过程连续赋值语句。但赋值对象可以是 reg 型变量,也可以是 wire 型变量。因为是无条件强制赋值,一般多用于交互式调试过程,不要在设计模块中使用。

1.13、模块与端口

结构建模方式有 3 类描述语句: Gate(门级)例化语句,UDP (用户定义原语)例化语句和 module (模块) 例化语句。

变量具体声明的位置不要求,但必须保证在使用之前的位置。

端口是模块与外界交互的接口。对于外部环境来说,模块内部是不可见的,对模块的调用只能通过端口连接进行。

模块的定义中包含一个可选的端口列表,一般将不带类型、不带位宽的信号变量罗列在模块声明里。

一个模块如果和外部环境没有交互,则可以不用声明端口列表。例如之前我们仿真时 test.sv 文件中的 test 模块都没有声明具体端口。

端口类型有 3 种: 输入(input),输出(output)和双向端口(inout)。

input、inout 类型不能声明为 reg 数据类型,因为 reg 类型是用于保存数值的,而输入端口只能反映与其相连的外部信号的变化,不能保存这些信号的值

output 可以声明为 wire 或 reg 数据类型。

端口隐式的声明为 wire 型变量,即当端口具有 wire 属性时,不用再次声明端口类型为 wire 型。reg 型端口要么在 module 声明时声明,要么在 module 实体中声明。

当端口有 reg 属性时,则 reg 声明不可省略。(设计代码中并没有声明为reg类型,所以test bench中使用reg是会报错的)

需要例化的模块端口与外部信号按照其名字进行连接,端口顺序随意,可以与引用 module 的声明端口顺序不一致,只要保证端口名字与外部信号匹配即可

如果某些输出端口并不需要在外部连接,例化时 可以悬空不连接,甚至删除。一般来说,input 端口在例化时不能删除,否则编译报错,output 端口在例化时可以删除。

1.14、模块例化

建议采用命名端口方式对模块进行例化。

建议 input 端口不要做悬空处理,无其他外部连接时赋值其常量

当例化端口与连续信号位宽不匹配时,端口会通过无符号数的右对齐或截断方式进行匹配。

信号名字可以与端口名字一样,但他们的意义是不一样的,分别代表的是 2 个模块内的信号。

generate 语句进行多个模块的重复例化,可大大简化程序的编写过程。

Verilog 中,通过使用一连串的 . 符号对各个模块的标识符进行层次分隔连接,就可以在任何地方通过指定完整的层次名对整个设计中的标识符进行访问。

层次访问多见于仿真中。Verilog 中,通过使用一连串的 . 符号对各个模块的标识符进行层次分隔连接,就可以在任何地方通过指定完整的层次名对整个设计中的标识符进行访问。

当一个模块被另一个模块引用例化时,高层模块可以对低层模块的参数值进行改写。这样就允许在编译时将不同的参数传递给多个相同名字的模块,而不用单独为只有参数不同的多个模块再新建文件。

1.15、函数

在 Verilog 中,可以利用任务(关键字为 task)或函数(关键字为 function),将重复性的行为级设计进行提取,并在多个地方调用,来避免重复代码的多次编写,使代码更加的简洁、易懂。

函数在声明时,会隐式的声明一个宽度为 range、 名字为 function_id 的寄存器变量,函数的返回值通过这个变量进行传递

函数主要有以下几个特点:
1)不含有任何延迟、时序或时序控制逻辑
2)至少有一个输入变量
3)只有一个返回值,且没有输出
4)不含有非阻塞赋值语句
5)函数可以调用其他函数,但是不能调用任务

Verilog 用关键字 automatic 来对函数进行说明,此类函数在调用时是可以自动分配新的内存空间的,也可以理解为是可递归的。因此,automatic 函数中声明的局部变量不能通过层次命名进行访问,但是 automatic 函数本身可以通过层次名进行调用。

1.16、任务

函数一般用于组合逻辑的各种转换和计算,而任务更像一个过程,不仅能完成函数的功能,还可以包含时序控制逻辑

任务没有返回值

进行任务的逻辑设计时,可以把 input 声明的端口变量看做 wire 型,把 output 声明的端口变量看做 reg 型。但是不需要用 reg 对 output 端口再次说明。

2、Verilog语言和c语言区别

(1)、c语言可以包含回车符 ‘\r’。Verilog字符串不能多行书写,即字符串中不能包含回车符。Verilog 将字符串当做一系列的单字节 ASCII 字符队列。

(2)、c语言用 # 符号标识预处理、头文件等。Verilog语言 ` 来标识

`define   S    2
`include         "../../param.v"
`include         "header.v"

(3)、c语言是 #elif。Verilog是 `elsif,中间多了个s

(4)、c语言的多个条件执行相同语句时,需要将每个条件用 && 连接。Verilog的条件语句,多个条件选项可以用逗号分开。

(5)、c语言是 switch(条件),case 条件:的形式。Verilog是case(条件),条件:的形式。且还有case 语句的变形casex、 casez,用来表示条件选项中的无关项。casex 用 “x” 来表示无关值,casez 用问号 “?” 来表示无关值
但是 casex、casez 一般是不可综合的,多用于仿真。

(6)、Verilog的i = i + 1 不能像 C 语言那样写成 i++ 的形式,i = i -1 也不能写成 i – 的形式。

Verilog语言- 和c语言的区别相关推荐

  1. HDL的综合和c语言的编译区别,Verilog HDL与C语言的比较

    Verilog HDL是在C语言的基础上发展起来的,因而它保留了C语言所独有的结构特点. 为便于对Verilog HDL有个大致的认识,在这里将它与C语言的异同作一比较: 1.C语言是由函数组成的,而 ...

  2. hdl语言哪种语言类似c,Verilog HDL笔记

    <设计与验证 Verilog HDL> 设计与验证的发展历程 早期:卡诺图设计,面包板验证 中期:原理图设计,EDA工具仿真验证 后期:硬件描述语言HDL设计,EDA工具仿真验证 抽象层次 ...

  3. C语言 memcpy 和 strcpy 函数区别 - C语言零基础入门教程

    目录 一.memcpy 函数/strcpy 函数简介 二.memcpy 函数/strcpy 函数实战 1.strcpy 函数属于字符串拷贝 2.memcpy 函数属于内存拷贝 三.猜你喜欢 零基础 C ...

  4. C语言 sizeof 和 strlen 函数区别 - C语言零基础入门教程

    目录 一.sizeof 函数与 strlen 函数区别 1.获取字符串长度 – 针对字符串 2.获取指针/数组长度 – 针对指针/数组 3.sizeof 获取内存大小 4.经典案例 二.猜你喜欢 零基 ...

  5. python动态与静态语言_静态语言和动态语言的区别

    via https://blog.csdn.net/hard_days/article/details/84967298 今天在群里聊天的时候,谈论到python和Java相比居然不用定义变量类型.我 ...

  6. c语言 python java_C语言、C++、Java,Python之间的区别,哪个更有前景,哪个更难 ?...

    从这四种语言的难度.受欢迎度还有作用以及优点缺点给楼主做一个全面的分析,我们可以从中了解其区别,以及难易程度.至于今后可以用到的或者是前景问题,根据自己的职业发展大家可以自己做个分析.最后会总结一下他 ...

  7. 数据分析学习笔记 —编译性语言和解释性语言区别

    Python -编译性语言和解释性语言区别 编译器与解释器 简单地说,编译器是一个程序,可以阅读以某一种语言(源语言)编写的程序,并把该程序翻译成一个等价的.用另一种语言(目标语言)编写的程序. 如果 ...

  8. c语言与编程语言的区别,C语言与其他编程语言的区别

    答案:C语言 主要因为它具有强大的功能.许多著名的系统软件, 如PC-DOS,DBASE Ⅳ都是由C语言编写的.用C语言加上一些汇编语言子程序, 就更能显示C语言的优势了.归纳起来C语言具有下列特点: ...

  9. C语言 strcpy 和 strcpy_s 函数区别 - C语言零基础入门教程

    目录 一.strcpy_s 函数/strcpy 函数简介 1.strcpy 函数语法 2.strcpy_s 函数语法 二.strcpy/strcpy_s 函数实战 三.猜你喜欢 零基础 C/C++ 学 ...

最新文章

  1. 启用CORS实现Ajax跨域请求
  2. 一个由跨平台产生的浮点数bug | 有你意想不到的结果
  3. 【剑指offer】最长不含重复字符的子字符串
  4. (四)DOM对象和jQuery对象
  5. 谷歌浏览器出现“远程计算机访问失败问题”
  6. Java知多少(18)类的定义及其实例化
  7. Linux安装与配置
  8. 2018-11-13#Hive外表创建和加载数据
  9. matlab滤波器函数6,matlab中滤波器函数filter的c语言实现
  10. Subline Text3进入Markdown语法编辑模式显示白屏怎么办?
  11. 论文查重 降重复度?如何进行毕业论文查重--总结贴
  12. 全志A31编译脚本 .
  13. hadoop源码编译(从0到1一步步教你如何编译,适用于任何hadoop版本)
  14. Ionic系列——Ionic介绍
  15. c语言-链表-贪吃蛇
  16. 【算法打卡(二分查找)---7.12】
  17. 简单说说 RPC 框架,你 悟到了吗?
  18. 编程中的心流模式flow
  19. 用Kubernetes部署超级账本Fabric的区块链即服务
  20. 夜雨数竞笔记-定积分(1)-区间再现公式

热门文章

  1. MinGW32编译ffmpeg+libsrt
  2. 浅谈yolov4中的一部分数据增强
  3. pg_repack 处理表和索引的膨胀
  4. c语言实现计算函数在某点的导数近似值
  5. ubuntu18安装Domoticz(内网穿透)和home assistant(docker安装)
  6. spring概念理解之IOC(控制反转)
  7. Spring的ioc控制反转
  8. 大数据实验室建设方案
  9. Excel翻译单元格内容
  10. 小程序自定义底部菜单栏