我对这个SystemVerilog代码有问题。以下是代码:
module mult ( multiplicand, multiplier, Product, 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我正在尝试用Booth的算法写一个输入32位的乘法器和64位的乘积。发生此错误:
always_comb构造不能推断纯粹的组合逻辑。
为什么会发生这种事?
发布于 2011-05-19 06:16:53
在always块中描述组合逻辑时,必须确保所有变量都分配给代码中所有路径中的值。否则,将推断出锁存。在传统的always块中很容易忽略这样的东西,因此在SystemVerilog中引入了always_comb块来显式地检查这一点。
在您的示例中,您有一些总线在case语句的每个分支中没有赋值,例如,mcand在分支nao_multiplicar和fim中没有分配给它的值。
有两个解决方案。首先是分配给所有代码分支中的所有变量。
另一种解决方案是在case语句之前为always_comb中的所有变量编写“默认值”。这样,每次always_comb块触发时,每个变量都将被赋值给一个值,并且不会出现警告。然后,YOur case语句只需要处理需要更改的变量:
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 发布于 2011-05-19 13:01:14
当我去掉initial块时,所有的编译错误都被消除了。我用的是来自Cadence和Synopsys的模拟器。
这里引用IEEE,1800-2009,第9.2.2.4节“顺序逻辑always_ff过程”:
always_ff过程施加的限制是,它只包含一个事件控件,而不包含阻塞定时控件。always_ff过程中赋值左侧的变量,包括被调用函数的内容中的变量,不应被任何其他进程写入。
always_comb也有类似的报价。
这些文档可以随时从IEEE获得。您的模拟器也应该有文档。
在这种情况下,您从工具中收到的错误消息似乎没有多大帮助。
发布于 2016-08-19 21:44:25
然而,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;
...
endhttps://stackoverflow.com/questions/6053338
复制相似问题