首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有always_comb构造的Systemverilog问题

具有always_comb构造的Systemverilog问题
EN

Stack Overflow用户
提问于 2011-05-19 03:11:10
回答 4查看 26.4K关注 0票数 2

我对这个SystemVerilog代码有问题。以下是代码:

代码语言:javascript
复制
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构造不能推断纯粹的组合逻辑。

为什么会发生这种事?

EN

回答 4

Stack Overflow用户

发布于 2011-05-19 06:16:53

always块中描述组合逻辑时,必须确保所有变量都分配给代码中所有路径中的值。否则,将推断出锁存。在传统的always块中很容易忽略这样的东西,因此在SystemVerilog中引入了always_comb块来显式地检查这一点。

在您的示例中,您有一些总线在case语句的每个分支中没有赋值,例如,mcand在分支nao_multiplicarfim中没有分配给它的值。

有两个解决方案。首先是分配给所有代码分支中的所有变量。

另一种解决方案是在case语句之前为always_comb中的所有变量编写“默认值”。这样,每次always_comb块触发时,每个变量都将被赋值给一个值,并且不会出现警告。然后,YOur case语句只需要处理需要更改的变量:

代码语言:javascript
复制
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     
票数 7
EN

Stack Overflow用户

发布于 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获得。您的模拟器也应该有文档。

在这种情况下,您从工具中收到的错误消息似乎没有多大帮助。

票数 3
EN

Stack Overflow用户

发布于 2016-08-19 21:44:25

然而,always_comb会推断组合逻辑,但是,在always_comb块中,您正在执行像C代码这样的赋值,例如:

代码语言:javascript
复制
always_comb
begin
  ...
  cont_aux   = cont + 1;
  cont       = cont_aux;
  ...
end

在这里,您要求建立一个组合逻辑与反馈。

如果您想要在时间中存储值,则必须将赋值放在always_ff块中,这将推断出顺序逻辑。

代码语言:javascript
复制
always_ff @(posedge clk)
begin
  ...
  cont <= cont + 1;
  ...
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6053338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档