Verilog标准手册阅读笔记
作者:互联网
引言
该文章不适用于Verilog入学
Verilog标准手册下载地址:
Verilog标准手册
简介
基本元件模块
:逻辑门和用户定义的原语模块(UDPs
)
NET
:表示电路连线或是总线的网络
寄存器
:可以作为输入信号连接到某个具体模块的输入口
模块中每个initial
,always
,连续赋值assign
,UDP
和各种逻辑门结构块
都是并行执行
代码编写标准
语汇代码
目的: 提高可读性和可维护性
要求:
-
每个Verilog源文件中只准编写一个模块,每个模块只能使用一个源文件
-
源文件的名字应该与内容相关(
其实EDA一般都会强制要求模块名和源文件名相同) -
每行只写一个声明语句或说明,同时需要使用缩进
-
变量的定义要做到见名知意,且保持统一的命名风格
-
编写模块的接口注释,指明接口的格式和功能
-
减少
硬编码
,多使用参数和宏定义
可综合代码
目的: 避免不可综合
要求:
-
按照功能进行模块分割,同时,使用行为风格去设计功能块,尽可能避免使用门级描述
-
建立一个定义良好的时钟策略,并在Verilog源代码中清晰地体现该策略,保证时钟和复位信号是干净的,即不会由其他组合电路产生该信号
-
建立一个定义良好的测试策略,使所有的触发器都是可复位的
-
描述组合和锁存逻辑的
always
块,必须在always
块开头的控制事件列表中列出所有的输入信号 (一般的EDA
工具对这条规则是默) -
所有的输出变量必须被各输入值的组合赋值
-
在
always
块中已被定义为输出的寄存器变量绝对不能再在该always
中读进来作为输入信号 -
时钟沿触发的
always
块必须是单时钟,并且任何异步控制输入必须在控制事件列表中列出来 -
避免生成额外的锁存器
在无时钟的always块中,由于有的输出变量被赋了某个信号变量值,而该信号变量没在该always块的电平敏感控制事件中列出,这会在综合中生成不想要的锁存器。
- 避免生成额外的触发器
在时钟沿触发的always 块中,用非阻塞的赋值语句对寄存器类型的变量赋值,综合后就会生成触发器;或者当寄存器类型的变量在时钟沿触发的always 块中经过多次循环它的值仍保持不变,综合后也会生成触发器。
-
所有内部状态寄存器必须是可复位的 (这并不适用于流水线或同步寄存器)
-
一般情况下,在赋值语句中不能使用延迟,使用延迟的赋值语句是不可综合的
-
不要使用整型和time型寄存器,否则将分别综合成32位和64位的总线。
-
仔细检查Verilog代码中使用动态指针,循环声明或算术运算部分,因为这类代码在综合后会生成大量的门,而且很难进行优化
设计流程
1. 系统分析
2. 系统划分
2.1 顶级模块
2.2 模块大小估计
2.3 预布局
3. 模块级设计
3.1 编写RTL级Verilog
3.2 综合代码检查
3.3 写Verilog测试文件
3.4 Verilog仿真
3.5 写综合约束,边界条件,层次
3.6 预综合以分析门的数量和延时
4. 芯片综合
4.1 写Verilog测试文件
4.2 Verilog仿真
4.3 综合
4.4 门级仿真
5. 测试
6. 布局布线
7. 布局布线后的仿真测试
Verilog使用注意事项
always
声明语句
always @(inputs) begin
//组合逻辑
end
注意事项:
- 在
always
块中被赋值的只能是寄存器类型的变量 - 如果
always
中没有时间控制将会无限循环
assign
连续赋值声明语句
当表达式中NET
或寄存器类型变量的值发生变化时,使用assign
可以在一个或更多的电路连接中创建事件
wire cout,cin;
wire[31:0] sum,a,b;
assign {cout,sum}=a+b+cin;
注意事项:
-
连续赋值语句必须放在
initial
和always
块外 -
连续赋值语句将被综合成为组合逻辑电路
begin
声明语句
- 在
begin-end
模块中至少要有一个声明语句,同时声明语句会被顺序执行
case
声明语句
-
不确定值和高阻值在
case
语句的表达式匹配中都代表“不必考虑” -
case
中的赋值语句常常被综合成多路器,如果变量被用作case
语句的标号,它就会被综合成优先编码器 -
在一个无时钟触发的
always
块中,如有不完整的赋值,他将被综合成透明锁存器 -
在一个有时钟触发的
always
块中,如有不完整的赋值,他将被综合成循环移位寄存器
标签:语句,always,笔记,手册,Verilog,模块,寄存器,赋值 来源: https://www.cnblogs.com/csycmcc8023/p/16408312.html