带有always_comb结构的Systemverilog问题
我对这个 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
我正在尝试使用 32 位输入和 64 位乘积编写一个乘法器 布斯算法。出现此错误:
always_comb 构造并不推断纯粹的组合逻辑
为什么会发生这种情况?
I have a problem with this SystemVerilog code. Here is the code:
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
I'm trying write a multiplicator with inputs of 32 bits and a product of 64 bits using
the Booth's algorithm. This error occur:
always_comb construct does not infer purely combinational logic
Why does this happens?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在
always
块中描述组合逻辑时,您必须确保所有变量都分配给代码中所有路径中的值。否则将推断出锁存器。在传统的always
块中很容易错过类似的内容,因此 SystemVerilog 中引入了always_comb
块来显式检查这一点。在您的情况下,您有一些总线没有在 case 语句的每个分支中分配值,例如
mcand
没有在分支nao_multiplicar
中为其分配值> 和fim
。有2种解决方案。首先是分配给所有代码分支中的所有变量。
另一种解决方案是在 case 语句之前的
always_comb
中为所有变量写入“默认”值。这样,每次always_comb
块触发时,每个变量都会被分配一个值,并且不会出现警告。那么我们的 case 语句只需要处理需要改变的变量:When describing combinational logic in
always
blocks, you have to make sure that all your variables are assigned to a value in all paths in your code. Otherwise a latch will be inferred. It's easy to miss something like this in traditionalalways
blocks, so thealways_comb
block was introduced in SystemVerilog to explicitly check for this.In your case, you've a few buses which are not assigned values in each branch of the case statement, for example
mcand
hasn't a value assigned to it in branchesnao_multiplicar
andfim
.There are 2 solutions. First is to, well, assign to all your variables in all your code branches.
Another solution is to write 'default' values for all of the variables in the
always_comb
before the case statement. In this way, each variable will always be assigned to a value each time thealways_comb
block triggers, and there'll be no warnings. YOur case statement then only needs to deal with the variables that need to change:当我删除
initial
块时,所有编译错误都被消除。我正在使用 Cadence 和 Synopsys 的模拟器。以下引用自 IEEE Std, 1800-2009,第 9.2.2.4 节“顺序逻辑always_ff 过程”:
always_comb
有一个类似的引用。该文档可以从 IEEE 轻松获得。您的模拟器还应该有文档。
在这种情况下,您从工具收到的错误消息似乎没有多大帮助。
All the compile errors are eliminated when I get rid of the
initial
block. I'm using simulators from Cadence and Synopsys.Here is a quote from the IEEE Std, 1800-2009, section 9.2.2.4 "Sequential logic always_ff procedure":
There is a similar quote for
always_comb
.The documentation is readily available from the IEEE. Your simulator should also have documentation.
The error message you receive from your tool seems not to be very helpful in this case.
always_comb 将推断组合逻辑,但是,在你的always_comb 块中,你正在执行像 C 代码一样的分配,例如:
在这里,你要求创建一个带有反馈的组合逻辑。
如果你想及时存储值,你必须将你的赋值放在一个always_ff块中,这将推断顺序逻辑。
always_comb will infer combinational logic, however, in your always_comb block you are doing assignments like C code, e.g:
Here you are asking to make a combinational logic with feedback.
If you want to store values in time, you have to put your assignments in an always_ff block, which will infer sequential logic.
LRM 是我用于系统 verilog 的最有用的文档
http://www.vhdl.org /sv/SystemVerilog_3.1a.pdf
The LRM is the most useful documentation I use for system verilog
http://www.vhdl.org/sv/SystemVerilog_3.1a.pdf