ysyx:0008:verilog & use of verilator

操作符和表达式
- 同类型操作符之间,除条件操作符从右往左关联,其余操作符都是自左向右关联。圆括号内表达式优先执行。
对变量进行声明时,要根据变量的操作符对变量的位宽进行合理声明,不要让结果溢出。上述例子中,相加的 2 个变量位宽为 4bit,那么结果寄存器变量位宽最少为 5bit。否则,高位将被截断,导致结果高位丢失。无符号数乘法时,结果变量位宽应该为 2 个操作数位宽之和。 - 负数表示时,可以直接在十进制数字前面增加一个减号 -,也可以指定位宽。因为负数使用二进制补码来表示,不指定位宽来表示负数,编译器在转换时,会自动分配位宽,从而导致意想不到的结果。
- 算术操作符如果操作数某一位为 X,则计算结果也会全部出现 X。
- 关系操作符的正常结果有 2 种,真(1)或假(0)。
- 如果操作数中有一位为 x 或 z,则关系表达式的结果为 x。
- 等价操作符包括逻辑相等(==),逻辑不等(!=),全等(===),非全等(!==)。
等价操作符的正常结果有 2 种:为真(1)或假(0)。
逻辑相等/不等操作符不能比较 x 或 z,当操作数包含一个 x 或 z,则结果为不确定值。
全等比较时,如果按位比较有相同的 x 或 z,返回结果也可以为 1,即全等比较可比较 x 或 z。所以,全等比较的结果一定不包含 x。
编译指令(类似于宏定义)
时延和时序控制
过程结构
所有结构正常情况下相互并行(各自产生独立的控制流)
initial 只进行一次
always 重复进行
更多时候,在设计电路时,always 时序逻辑块中多用非阻塞赋值,always 组合逻辑块中多用阻塞赋值;在仿真电路时,initial 块中一般多用阻塞赋值。
一个避免时序冒险的例子
顺序块 begin…end
并行块 fork…join
命名块(可以相互控制和访问)
disable 在 always 或 forever 块中使用时只能退出当前回合,下一次语句还是会在 always 或 forever 中执行。因为 always 块和 forever 块是一直执行的,此时的 disable 有点类似 C 语言中的 continue 功能。
控制流
其他注意事项
语法正确的代码并不一定能产生功能正常的电路,一般来说都是因为不小心引入了锁存器造成的。如上述例子所示,除了指定的情况外(cpu_overheated),还有一些其它情况,这时会发生什么?在 verilog 中,其结果就是保持不变,这意味着要记住当前状态,从而产生了锁存。
使用case实现组合逻辑时,必须有default,以防出现锁存器
Reference
未解之谜
1 | module my_dff8( |
为什么必须要用线网relay一下???
在设计Verilog模块时,请遵循以下原则:
在组合逻辑的always块内采用阻塞赋值
时序逻辑的always块内采用非阻塞赋值
违背这一原则将可能导致难以发现的电路错误,且可能导致仿真与综合的不一致,请用户切记。至于为何这样,初学者可以不必理会,简单理解为verilog语法规范性要求即可。
不初学呢???
模块库
1 | module dff(input clk,input d,output reg q); |
1 | module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout ); |
- Post title:ysyx:0008:verilog & use of verilator
- Post author:Jackcui
- Create time:2023-08-19 11:18:23
- Post link:https://jackcuii.github.io/2023/08/19/ysyx0008/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
Comments