2011-05-19 205 views
1

我有这个Systemverilog代码的问题。 我是这个语言的新手,非常不方便 找到有关此语言的文件。 这里是代码:使用always_comb构造的Systemverilog问题

模块mult(被乘数,乘数,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位输入和使用 布斯的algoritm 64位的产品乘数。发生此错误:“always_comb构造不会推断纯粹的组合逻辑”。为什么会发生?

+2

一个最小的例子,显示你的问题会hlep。 – 2011-05-21 17:14:08

回答

4

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

在你的情况下,你有几条总线在case语句的每个分支中都没有赋值,例如mcand在分支nao_multiplicarfim中没有赋值给它。

有2种解决方案。首先是分配所有代码分支中的所有变量。

另一种解决方案是在case语句之前为always_comb中的所有变量写入“默认”值。通过这种方式,每次always_comb块触发时,每个变量将始终分配一个值,并且不会有任何警告。那么你的case语句只需要处理那些需要改变的变量:当我摆脱initial

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  
+0

我做了你建议的更改,但问题仍然存在。 always_comb开头的默认值修正了错误 ,但状态保持不变。变量Product保留 值零。 – 2011-05-20 20:01:24

3

所有的编译错误被淘汰。我正在使用Cadence和Synopsys的模拟器。

下面是从IEEE标准,1800至2009年报价,节9.2.2.4“顺序逻辑always_ff过程”:

的always_ff过程强加限制 使其包含一个和 只有一个事件控制和不阻止时间控制。 内 包含 被调用函数的always_ff过程的变量, 不应被任何其他过程写入 。

还有类似的报价为always_comb

该文档可从IEEE获得。你的模拟器也应该有文档。

您从工具收到的错误消息在这种情况下似乎不是很有用。

0

的LRM是最有用的文档,我用系统的Verilog

http://www.vhdl.org/sv/SystemVerilog_3.1a.pdf

+2

LRM已过时并已过时。在标准化过程中进行了一些更改。这比没有好,但我强烈建议获得IEEE标准1800。 – 2011-06-22 18:55:49

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