Verilog HDL语言基础语法

Verilog HDL语言基础语法

  1. 标识符区分大小写,关键字是小写的,标识符可以是字母、数字、$(美元符号)和下划线的任意组合,只要第一个字符是字母或者下划线即可。
  2. 归约与按位运算符
    做一元运算符时是归约 ,二元时是按位运算符。

例如:当“&”作为一元运算符时表示归约与。&m 是将 m 中所有比特相与,最后的结果为1bit。
当“&”作为二元运算符时表示按位与。m&n 是将 m 的每个比特与 n 的相应比特相与,在运算的时候要保证 m 和 n 的比特数相等,最后的结果和 m(n)的比特数相同。

  1. 移位运算符
    都是用0来填充空闲位,一个二进制数不管原数值是多少,只要一直移位,最终全部会变为0。
  2. 条件运算符
    条件运算符为“ ? : ”,它是一个三元运算符,即有三个参与运算的量。从右往左结合。

if-else 也可以实现这种功能,但是 if-else 只能在 always 块中使用,不能在 assign 中使用,如果我们想在 assign 中使用就需要用到条件运算符。

  1. 优先级
    归约运算符 > 算数运算符 > 移位运算符 > 关系运算符 > “= =”和“!=”> 按位运算符 > “&&”和“||”> 条件运算符,总的来说是一元运算符 > 二元运算符 > 三元运算符。
    如果在编写代码的时候对这些关系容易混淆,最好的方式就是使用“( )”增加优先级。
  2. 位拼接运算符
    位拼接运算符由一对花括号加逗号组成“{ , }”,拼接的不同数据之间用“,”隔开。
    位拼接运算符的作用主要有两种,一种是将位宽较短的数据拼接成一个位宽长的数据;
    另一种是可以通过位拼接实现移位的效果。

位拼接运算
7. case语句
注意与c语言switch case语句的区别

case(<控制表达式>)
<分支语句 1> : 语句块 1;
<分支语句 2> : 语句块 2;
<分支语句 3> : 语句块 3;
………
<分支语句 n> : 语句块 n;
default : 语句块 n+1;

在执行了某一分支项内的语句后,跳出 case 语句结构,终止 case 语句的执行。case 语句中各个“分支项表达式”的取值必须是互不相同的,否则就会出现矛盾现象。

  1. inout 双向端口
    作为数据的输入输出端口 ,一般会同时定义一个变量来确定是输入还是输出端口。
  2. 系统任务和系统函数
    具体参考资料书(征途Pro《FPGA Verilog开发实战指南——基于Altera EP4CE10》2021.7.10(上) 8.3.16),他们都是在仿真时才会用到,可以用的时候查阅。
写完两个项目的语法总结

对于RTL代码,可分为两个部分:

(1)对模块输入输出变量定义
(2)根据波形图和逻辑编写后部分代码

对于Testbench仿真代码,大致分为五个部分

(1)时间尺度与精度单位,端口列表为空,直接列出“模块名 ();”
(2)定义待测试的RTL模块的输入(reg型)输出(wire型)变量
(3)初始化变量
(4)产生模拟输入变量
(5)模块实例化,注意信号名的对应关系和连线

  1. initial不可综合的(综合后不可以生成对应的硬件电路),常用于 Testbech 中初始化信号,但也可以在可综合的模块中用于初始化寄存器。
  2. begin end语句,是对多条语句赋值使用,但设计 RTL 代码的原则是一个 always 块中最好只有一个变量,所以 begin…end 在 RTL 代码中几乎很少使用,而在 Tetbench 中使用的更多。
  3. #延时,是不可综合的,但可以在可综合的模块中使用,其延时单位仍由可综合模块中的`timescale 决定,但是综合时被其延时时间被综合器忽略。
  4. 注意always和assign语句的区别,如果输出在 always 块中被赋值(即在“<=”的左边)
    就要用 reg 型变量,如果输出在 assign 语句中被赋值(即在“=”的左边)就要用 wire 型变量。
  5. $timeformat(-9, 0, “ns”, 6);

设置显示的时间格式,此处表示的是(打印时间单位为纳秒,小数点后打印的小数位为 0 位,时间值后打印的字符串为“ns”,打印的最小数量字符为 6 个).

  1. 只要监测的变量(时间、A, B, sel, out)发生变化,就会打印出相应的信息

$monitor(“@time %t:A=%b B=%b sel=%b out=%b”, $time, A, B, sel, out);

结合上面5和6,打出信息如下
样例

阻塞赋值和非阻塞赋值
  1. 阻塞赋值 “=” 电路结构与触发沿没有关系,只与输入电平的变化有关。

只要赋值号右边的表达式的值有变化,赋值号左边的表达式的值也将立刻变化。
按顺序执行;

  1. 非阻塞赋值 “<=” 电路结构与触发沿有关系,只有在触发沿时刻才能进行非阻塞赋值。

赋值号右边的表达式的值有变化,赋值号左边的表达式的值也不会立刻变化,需要等待下一次时钟沿到来时一起变化.
并行执行

非阻塞操作只能用于对寄存器类型变量进行赋值,因此只能用于“initial”和“always”块中,不允许用于连续赋值“assign”。

  1. 两者的用法
    3.1 编写时序逻辑----非阻塞赋值
    3.2 用always写组合逻辑代码----阻塞赋值
    3.3 同一个always块中不要都使用阻塞和非阻塞赋值
    3.4 一个always尽量只对一个变量赋值,虽然可以多个,但不推荐,不易后期维护和修改
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值