Verilog &引用&书信电报;信号>;不是一个常数;if语句中的错误

Verilog &引用&书信电报;信号>;不是一个常数;if语句中的错误,verilog,Verilog,我试图编写一个简单的模块,根据四个输入信号的值输出一个14位的数字。我的尝试如下所示 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 ass

我试图编写一个简单的模块,根据四个输入信号的值输出一个14位的数字。我的尝试如下所示

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
编译后,我收到以下错误:

错误:HDLCompiler:44-第67行:c不是常量

我不明白为什么如果前面的另外两条语句不起作用,那么这个特定的if语句就不起作用了。我试着把条件改为

if (c == 1) begin
但是没有用

有人知道如何解决这个错误吗?谢谢大家!

两个问题:

1) 您需要将
if
语句放在
始终
块中

如果您使用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

正如@Tim已经回答的那样,在
中使用
reg
类型始终
块或
wire
分配


@Tim也描述了嵌套的三元赋值,虽然在这个例子中写得很好,但它们通常被视为不好的实践。它们意味着一条很长的组合路径,很难维持。组合路径可通过合成进行优化,合成应暗示具有优化选择逻辑的mux

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

我的实现是使用casez,(?are't cares)。我发现每个值的优先级更容易查看/调试

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

非常感谢。我总是带着嵌套的三元作业,非常有趣。我试试看。非常感谢!编译器认为这些是条件生成项,而不是条件语句。“它们通常被视为坏习惯”。你有这项索赔的来源吗?我不认为它会产生比case语句更糟糕的路径,即使是简单的编译器优化,在更复杂的设计中,我认为您还应该添加一个默认情况,将输出分配给X。这是我喜欢三元分配的另一个原因,因为如果您不小心,if/else和case语句可能会对验证中的X传播产生危险的影响。如果您模拟这个,并且a/b/c/d是X,那么三元赋值将把X传播到输出(理想),If/else将输出14'h0333,casez语句将锁定以前的值,因为它没有默认语句。通常情况下,我所做/给出的每一次代码检查都是错误的。公司编码指南。我对使用大量嵌套三元运算符的旧代码库的维护经验。每一位指导我的人也都强调要避免使用它们,因为在调试它们时会遇到麻烦,因为它们不能按预期工作。正如@Tim所建议的那样,吞咽X是调试的一个问题,我添加了一个默认语句。>“它们通常被视为不好的做法”。你有这项索赔的来源吗?我不确定我先前的回答是否符合预期。我受到周围人的设计偏好的影响。在Ruby中也有三元运算符,我在社区代码评论中看到,嵌套运算符的使用混淆了代码,降低了可读性。对我来说,这是一个代码可读性问题@Tim yours是我见过的最清晰的例子,并不是每个人都对代码格式如此小心。