我对此Systemverilog代码有疑问。 我是这种语言的新手,非常困难 查找有关此语言的相关文档。 这是代码:
模块mult(被乘数,乘数,乘积,clk,clear,Startm,endm);
input [31:0] multiplicand;
input [31:0] multiplier ;
input clk;
input clear;
input Startm;
output logic [63:0] Product;
output logic endm;
enum logic [1:0] { inicio, multiplicar, nao_multiplicar, fim } estados;
logic [1:0] state;
logic [31:0] mplier;
logic [31:0] mplier_aux;
logic [31:0] mcand ;
logic [31:0] mcand_aux;
logic [63:0] Prod ;
logic [63:0] Prod_aux;
logic [5:0] cont;
logic [5:0] cont_aux;
initial begin
mplier = multiplier;
mplier_aux = multiplier;
mcand = multiplicand;
mcand_aux = multiplicand;
Prod = 0;
Prod_aux = 0;
state = inicio;
cont = 0;
cont_aux = 0;
end
always_ff @( posedge clk )
begin
if( clear )
begin
state <= inicio;
end
else if ( Startm )
begin
case( state )
inicio :
begin
if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
multiplicar :
begin
if( cont == 32 )
state <= fim;
else if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
nao_multiplicar:
begin
if( cont == 32 )
state <= fim;
else if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
fim:
begin
state <= inicio;
end
endcase
end
end
always_comb
begin
case(state)
inicio:
begin
mplier = multiplier;
mcand = multiplicand;
Prod = 0;
cont_aux = cont + 1;
cont = cont_aux;
end
multiplicar:
begin
mcand_aux = mcand << 1;
mcand = mcand_aux ;
mplier_aux = mplier >> 1;
mplier = mplier_aux ;
Prod_aux = Prod + mcand;
Prod = Prod_aux;
cont_aux = cont + 1;
cont = cont_aux;
end
nao_multiplicar:
begin
cont_aux = cont + 1;
cont = cont_aux;
end
fim:
begin
Product = Prod;
endm = 1;
end
endcase
end
endmodule
我正在尝试使用32位输入和64位乘积来编写乘法器 布斯的算法。发生此错误:“always_comb构造不会推断出纯粹的组合逻辑”。为什么会这样?
答案 0 :(得分:4)
在always
块中描述组合逻辑时,必须确保将所有变量分配给代码中所有路径中的值。否则将推断出锁存器。在传统的always
块中很容易错过这样的内容,因此在SystemVerilog中引入了always_comb
块以明确检查这一点。
在您的情况下,您在case语句的每个分支中都有一些未分配值的总线,例如mcand
没有在分支nao_multiplicar
和{fim
中分配给它的值{1}}。
有两种解决方案。首先是,分配给所有代码分支中的所有变量。
另一个解决方案是在case语句之前为always_comb
中的所有变量写入'default'值。通过这种方式,每次always_comb
块触发时,每个变量将始终分配给一个值,并且不会有任何警告。然后,你的案例陈述只需要处理需要改变的变量:
always_comb
begin
// Defaults (I think I got them all)
mplier = multiplier;
mcand = multiplicand;
Prod_aux = 0;
Prod = 0;
cont_aux = 0;
cont = 0;
Product = 0;
endm = 0;
// Now override the defaults when appropriate
case(state)
inicio:
begin
mplier = multiplier;
mcand = multiplicand;
Prod = 0;
cont_aux = cont + 1;
cont = cont_aux;
end
multiplicar:
begin
mcand_aux = mcand << 1;
mcand = mcand_aux ;
mplier_aux = mplier >> 1;
mplier = mplier_aux ;
Prod_aux = Prod + mcand;
Prod = Prod_aux;
cont_aux = cont + 1;
cont = cont_aux;
end
nao_multiplicar:
begin
cont_aux = cont + 1;
cont = cont_aux;
end
fim:
begin
Product = Prod;
endm = 1;
end
endcase
end
答案 1 :(得分:3)
当我摆脱initial
块时,所有编译错误都被消除了。我正在使用Cadence和Synopsys的模拟器。
以下是IEEE Std,1800-2009,第9.2.2.4节“顺序逻辑always_ff过程”的引用:
always_ff程序强制执行 限制它包含一个和 只有一个事件控件而且没有阻塞 时间控制。关于的变量 内部任务的左侧 一个always_ff程序,包括 来自a的内容的变量 被称为函数,不得写入 通过任何其他过程。
always_comb
有类似的引用。
可以从IEEE获得该文档。你的模拟器也应该有文档。
在这种情况下,您从工具收到的错误消息似乎不是很有帮助。
答案 2 :(得分:0)
LRM是我用于系统verilog的最有用的文档
答案 3 :(得分:0)
always_comb将推断组合逻辑,但是,在您的always_comb块中,您正在执行C代码之类的赋值,例如:
always_comb
begin
...
cont_aux = cont + 1;
cont = cont_aux;
...
end
在这里,您要求通过反馈制作组合逻辑。
如果要及时存储值,则必须将分配放在always_ff块中,这将推断顺序逻辑。
always_ff @(posedge clk)
begin
...
cont <= cont + 1;
...
end