目录
- 6.1 Verilog 通用目的always块
- 6.2 SystemVerilog 特有的过程块
- 6.2.1 组合逻辑过程块
- 6.2.2 锁存逻辑过程块
- 6.2.3 时序逻辑过程块
- 6.3 对任务和函数的改进
- 6.3.1 任务和函数的隐式语句组
- 6.3.2 函数返回值
- 6.3.3 在任务和函数结束前返回
- 6.3.4 空函数
- 6.3.5 使用名称传递任务/函数的参数
- 6.3.6 增强型函数形式参数
- 6.3.7 无形式参数的函数
- 6.3.8 形式参数的缺省方向和类型
- 6.3.9 缺省的形式参数值
- 6.3.10 数组、结构体和联合体作为形参
- 6.3.11 用引用取代复制类传递参数
- 6.3.12 命名的任务和函数结尾
- 6.3.13 空任务和函数
SystemVerilog新增内容:
- 组合逻辑过程块:always_comb
- 锁存逻辑过程块:always_latch
- 时序逻辑过程块:always_ff
- 改进任务和函数
6.1 Verilog 通用目的always块
- always块
是一个能重复执行块中语句的无限循环。为了使仿真时间向前推进,循环中必须包含一些时间控制或事件控制语句。 - 敏感表
在always开头所写的边沿敏感的事件控制条件。 - 用法
- 在RTL级,always过程块可以用作组合逻辑、锁存逻辑和时序逻辑的建模。
- 用于更抽象的逻辑建模。
- always块的硬件推断
综合编译和形式工具必须检查过程块中的语句以及它的事件控制条件来判断该块描述的硬件类型。 - 存在的问题
- 推断硬件类型的过程增加了软件工具的负担,甚至可能出错。
- Verilog通用的always块的建模指导原则可能不被其他工具采用,可能造成仿真和综合结果不一致。
6.2 SystemVerilog 特有的过程块
SystemVerilog新增3个特有的可综合的过程块:always_comb(组合逻辑过程块)、always_latch(锁存逻辑过程块)和always_ff(时序逻辑过程块)
解决的问题:
- 明确了设计的意图,如果意图与逻辑不匹配软件工具将发出警告。
- 设计思路清晰,便于维护。
6.2.1 组合逻辑过程块
always_comb组合逻辑过程块表示建立组合逻辑模型。
对比项目 | always@(*) | always_comb |
敏感表 | 需要指明或者用通配符* | 自动推断 |
敏感表范围 | 过程块中的额所有变量以及任务/函数调用的参变量 | 对块内读取的信号和块内调用的函数读取的信号都敏感。 |
触发 | 至少一个敏感信号改变 | 除敏感表触发外,在零时刻自动执行确保输出与输入值的一致性(在零时刻产生与输入相对应的输出结果)。具体见例子1 |
例子1:零时刻保输出与输入值的一致性
- always @(state):仿真开始时变量都state和nextState为缺省值0,即WAITE,当时钟上升沿到来,将会导致仿真结果锁定。
- always_comb:仿真开始时变量都state和nextState为缺省值0,即WAITE,然后执行一次always_comb块,nextState变为LOAD,正常仿真。
注意:实际硬件不会出现问题,实际硬件组合逻辑的输出肯定反应改逻辑的输入值。
module controller (
output logic read,write ,
input instr_t instruction ,
input logic clock,resetN
);
enum {WAITE,LOAD,STORE} state, nextState;
always @(posedge clock or negedge resetN)
begin
if(~resetN)
state <= WAITE;
else
state <= nextState;
end
always @(state)//always_comb
begin
case (state)
WAITE: nextState <= LOAD;
LOAD: nextState <= STORE;
STORE: nextState <= WAITE;
endcase
end
always @(state, instruction)
begin
read = 0;
write = 0;
if (state == LOAD && instruction == FETCH)
read = 1;
else if (state == STORE && instruction == WRITE)
write = 1;
end
endmodule
6.2.2 锁存逻辑过程块
- always_latch过程块表示过程块描述的是基于锁存器的逻辑。
- 敏感列表也是自动推断。
- 也会在零时刻自动执行一次。
与always_comb相比:
- 软件认为设计的意图是描述锁存逻辑。
- 代码检查与组合逻辑不同。如在锁存逻辑中,过程块的输出变量不需要对所有可能的输入条件响应。
always_latch
if (enable) q <= d;
如果上面的用的是always_comb就会报错,因为组合逻辑需要对所有输入条件响应。
6.2.3 时序逻辑过程块
- always_ff专用过程块表示设计的意图是描述可综合的时序逻辑。
- always_ff过程块要求明确指定敏感表中的信号是posedge或者negedge。
6.3 对任务和函数的改进
6.3.1 任务和函数的隐式语句组
Verilog | SystemVerilog |
任务或者函数中有多条语句时必须写在begin…end,对于任务也允许使用fork…join结构 | 任务和函数有多条语句时不需要begin…end对多条语句进行打包。 |
6.3.2 函数返回值
Verilog | SystemVerilog |
函数名本身就是一个与该函数类型相同的变量,函数的返回值通过对函数名的赋值产生 | 增加return语句,且return语句优先级高于用函数名 |
6.3.3 在任务和函数结束前返回
Verilog | SystemVerilog |
当遇到endtask或endfunction标明的任务或函数结尾时,才会退出任务或函数。 | 使用return语句可以在执行流的任何时刻退出任务或函数。 |
6.3.4 空函数
Verilog | SystemVerilog |
函数必须有返回值,当被调用时,必须获得返回值 | 增加void类型,表示函数没有返回值 |
- 增加output和input形式参数,可以用以传送调用函数所产生的变化。
- 在可综合的模块中,用空函数代替任务。
6.3.5 使用名称传递任务/函数的参数
Verilog | SystemVerilog |
必须按照任务或函数定义的形参顺序传递数值。 | 增加使用形参名称传递数值。方法与引用端口一样.<形参名字>(实参名字) |
6.3.6 增强型函数形式参数
Verilog | SystemVerilog |
只允许有输入。函数的唯一输出就是它的返回值。 | 允许函数的形式参数就像任务一样,可以声明为input、output和inout。函数可以有任意个输出以及函数的返回值。 |
function [63:0] add (
input [63:0] a,b,
outptu overflow
)
{overflow,add} = a + b;
endfunction
为了防止出现不合要求的以及不可综合的边缘效应,Systemverilog对何处能调用有output或input参数的函数进行了一定的限制,不能用于:
- 事件表达式
- 使用过程持续赋值的表达式
- 不在过程语句内的表达式
6.3.7 无形式参数的函数
Verilog | SystemVerilog |
允许任务有零个或者任意数目个形式参数。但是要求函数至少有一个输入的形式参数,即使这个参数从未使用。 | 允许函数没有形式参数 |
6.3.8 形式参数的缺省方向和类型
Verilog | SystemVerilog |
任务或函数所有形式参数都是reg类型 | 任务和函数的缺省类型时logic,形式参数的缺省方向为input。 |
6.3.9 缺省的形式参数值
与C语言一样。SystemVerilog允许任务与函数为每个形参定义一个可选的缺省值。
6.3.10 数组、结构体和联合体作为形参
SystemVerilog允许 非压缩数组 、压缩或非压缩结构体 和 压缩或非压缩或标签联合体 传递进/出任务和函数。
6.3.11 用引用取代复制类传递参数
类似C语言的引用,为了通过引用传递数值,相参用关键字ref取代方向关键字input、output或者inout进行声明。
- 只有自动任务和函数可以具有ref参数。
- 通过将形式参数声明为const_ref类型,可以将引用形式参数声明为只允许对引用的对象进行读操作。
- 任务ref参数对变化敏感。
- ref参数可以读取当前值。
- ref参数可以立即传播变化。
- 带有ref形参的函数可以修改函数外部变量的值,因此带有输出参数的函数有相同的限制。
- 事件表达式
- 持续赋值中的表达式
- 过程持续赋值的表达式
- 不在过程语句内的表达式
6.3.12 命名的任务和函数结尾
SystemVerilog允许用关键字endtask和endfunction指定名称。增加代码可读性。
enstask: <task_name>
endfunction: <function_name>
6.3.13 空任务和函数
为非完整的代码预留空间,方便自顶向下设计。
Verilog | SystemVerilog |
任务和函数至少要包含一条语句(即使时空的begin…end) | 允许任务和函数完全为空,及不包含任何语句或语句组。 |