always_comb代表组合逻辑
always_comb过程块表示建立组合逻辑模型
always_comb
if(!mode)
y = a + b;
else
y = a - b;
always_comb能推断出其敏感表
与通用always过程块不同,always_comb块的后面不需要指明敏感表。软件工具已经知道设计的意图是建立一个组合逻辑模型,因此这个组合逻辑的敏感表可以是自动推断出来的。推断的敏感表包含了所有被过程块读取(所谓读取即信号出现在表达式右边或作为条件语句的条件表达式中,下同)并在块外赋值的信号。那些在此过程中被阻塞赋值语句赋值并且只在该过程块读取的临时变量不包括在敏感表中。SystemVerilog的敏感表中还包括过程中调用函数的所有信号,但只被函数赋值和读取的临时变量除外。
禁止出现共享变量
always_comb过程块仍然要求被赋值的变量不能再次在其他过程被赋值。这样限制避免了非组合逻辑的共享变量的出现。这种限制也符合综合的指导原则,并且确保了所有的软件工具(不仅仅是综合工具)都采用同样的建模规则。
无歧义的设计意图
零时刻自动求值
always_comb确保输出与输入值保持时间一致
always_comb过程块与always过程块的另一个不同之处在于,在所有initial和always过程块启动后,always_comb块会在仿真的零时刻自动出发。不管推断出的敏感表中的信号是否发生了变化,这样的自动求值都会发生。always_comb的这种特殊的语义确保了组合逻辑在零时刻产生与输入相对应的输出结果。特别是在使用缺省值为逻辑0的两态变量建模时,这种零时刻的自动求值显得尤为重要,复位信号很可能不会引起组合逻辑的敏感表中的信号发生变化。而如果没有变化,通用always过程块不会被触发,从而使输出变量也不会变化。
一个采用枚举类型建模的简单有限状态机。
三个可能的状态是WAITE、LOAD、STORE
。状态机复位后处于WAITE状态。状态机的
组合逻辑会对当前状态进行解码,如果当前
状态的组合逻辑为WAITE,则下一个状态为LOAD。
在每个clock信号的上升沿,状态时序逻辑都会将
变量NextState的值赋给变量State
module controller(
output logic read,write,
input instr_t instruction,
input logic clock,resetN
);
enum {WAITE,LOAD,STORE}State,NextState;
always@(posedge clock,negedge resetN)
if(!resetN) State <= WAITE;
else State <= NextState;
always@(State)
begin
case(State)
WAITE:NextState = LOAD;
LOAD:NextState = STORE;
STORE:NextState = WAITE;
encase
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
endmoudle
module controller(
output logic read,write,
input instr_t instruction,
input logic clock,resetN
);
enum {WAITE,LOAD,STORE}State,NextState;
always@(posedge clock,negedge resetN)
if(!resetN) State <= WAITE;
else State <= NextState;
always_comb
begin
case(State)
WAITE:NextState = LOAD;
LOAD:NextState = STORE;
STORE:NextState = WAITE;
encase
end
always_comb
begin
read = 0; write = 0;
if(State == LOAD && instruction == FETCH) read = 1;
else if(State ==STORE && instruction == WRITE) write = 1;
end
endmoudle
always_comb敏感列表包含函数读取的信号
SystemVerilog中的always_comb过程块则消除了@*的这点缺陷。always_comb过程块内读取的信号和块内调用的函数的信号都敏感。这样编写函数时就不需要形式参数了。在设计过程中,即使函数引用的信号的发生变化,也不需要修改函数形式参数列表和调用函数的代码。
always_comb过程块会对data、sel、c、d和e敏感
always@* //推断出@(data)
begin
a1 = data << 1;
b1 = decode();
...
end
always_comb //推断出@(data,sel,c,d,e)
begin
a2 = data << 1;
b2 = decode();
...
end
funciton decode;//不带输入的函数
begin
case(sel)
2'b01: decode = d|e;
2'b10:decode = d&e;
default : decode = c;
endcase
end
endfunction