2012-08-06 53 views
4

我想写一个简单的模块来输出一个14位数的基础上,四个输入信号的值。我的尝试如下所示。“<signal>是不是一个常数”错误在if语句

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output [13:0] size 
); 

    if (a) begin 
     assign size = 14'h2222; 
    end 
    else begin 
     if (b) begin 
      assign size = 14'h1111; 
     end 
     else begin 
      if (c) begin 
       assign size = 14'h0777; 
      end 
      else begin 
       assign size = 14'h0333; 
      end 
     end 
    end 

endmodule 

在编译时,我收到以下错误:

ERROR:HDLCompiler:44 - Line 67: c is not a constant

我不明白为什么那个特定的if语句不若其他两个工作之前它是。我试图改变的条件

if (c == 1) begin 

但无济于事。

有谁知道如何解决这个错误?谢谢!

+0

编译器认为这些是条件生成项目,而不是条件语句。 – 2012-08-07 03:04:15

回答

6

两个问题:

1)你需要把if报表always块内。

如果您使用的Verilog-2001,您可以使用

always @* 
    if .... 
    end 
end 

否则指定的敏感性列表中的所有输入:

always @(a or b or c or d) 
    if .... 
    end 
end 


2)恒定分配不会允许入内if语句。

if块内的所有语句删除assign关键字:

if (a) begin 
    size = 14'h2222; 
end 

您还必须声明大小为reg类型。

但是,我的首选是用条件操作符重写整个模块,我发现它更喜欢阅读。这下面的模块实现相同的结果:

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output [13:0] size 
); 

    assign size = a ? 14'h2222 : 
        b ? 14'h1111 : 
        c ? 14'h0777 : 
         14'h0333 ; 

endmodule 
+0

实现了(1)和(2),它似乎很好。 – 2012-08-06 22:06:18

+0

谢谢!我总是与@(*) – 2012-08-06 22:06:55

+0

一起去嵌套三元任务,非常有趣。我会试一试。谢谢一堆! – 2012-08-06 22:29:36

1

正如@Tim已经回答了,用reg类型里面always块或wireassign

@Tim也描述了嵌套三元赋值,而在这个例子中写得很好,他们通常被认为是不好的做法。它们意味着很长的组合路径并且难以维护。组合路径可以通过合成来优化,这应该暗示具有优化选择逻辑的多路复用器。

更容易维护代码将拥有较低的拥有成本,只要它不会导致更大的综合设计,通常是首选。

我的实现是使用casez(?不关心)。我发现每个值的优先级更易于查看/调试。

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output logic [13:0] size //logic (SystemVerilog) or reg type 
); 

always @* begin 
    casez ({a,b,c}) 
    3'b1?? : size = 14'h2222 ; 
    3'b01? : size = 14'h1111 ; 
    3'b001 : size = 14'h0777 ; 
    3'b000 : size = 14'h0333 ; 
    default: size = 'bx  ; 
    endcase 
end 

endmodule 
+0

“他们通常被认为是不好的做法”。你有这个说法的来源吗?我不认为它会产生比案例陈述更糟糕的路径,因为即使是微不足道的编译器优化。 – Tim 2012-08-08 17:14:19

+0

另外,虽然我知道这是一个微不足道的模块,有些设计偏好,但在一个更复杂的设计中,我相信你还应该添加一个将输出分配给X的默认情况。这是我更喜欢三元赋值的另一个原因,如果您不小心,if/else和case语句可能会对验证中的X-Propagation产生危险影响。如果你模拟这个,并且a/b/c/d是X,那么三元赋值将把X传播到输出(理想),if/else将输出14'h0333,并且casez语句将锁定之前的值,因为它没有默认声明。 – Tim 2012-08-09 01:16:12

+0

一般不好的做法,我已经/给出了每个代码审查。公司编码指南。我在使用大量嵌套三元运算符的旧代码库上进行维护的经验。每一位为我提供指导的人也都避免了这些问题,因为如果不按预期工作,那么在调试时会遇到麻烦。 – Morgan 2012-08-09 08:03:51