如何为组合中的输出分配默认值始终阻塞,因此即使使用了不完整的if-else语句,也不会推断锁存器

时间:2013-11-20 00:13:03

标签: verilog

假设我想编写一个使用4个输入和3个输出的组合模块。为了模拟我的逻辑,我做了类似的事情:

module ifelse (
      input wire a,
      input wire b,
      input wire c,
      input wire d,
      output reg y1,
      output reg y2,
      output reg y3
      );

     always @* begin

       if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
         end
       else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
         end
       else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
       end
   end
endmodule

好的,我知道此代码会推断y1y2y3的锁存器,避免这种情况的方法是始终为每个人分配一个值每个if-else块中的LHS,如下所示:

module ifelse (
      input wire a,
      input wire b,
      input wire c,
      input wire d,
      output reg y1,
      output reg y2,
      output reg y3
      );

     always @* begin

       if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
         y2 = 1'bx;
         end
       else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
         y3 = 1'bx;
         end
       else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
         y1 = 1'bx;
       end
       else begin
         y1 = 1'bx;
         y2 = 1'bx;
         y3 = 1'bx;
       end
   end
endmodule

但是现在,想象一下有很多if-else块(我试图描述一个教学微处理器的控制单元),并且有很多输出来自这个模块(控制线)对于微处理器数据路径中的所有寄存器)。必须为每个if-else块中的每个输出分配一个值肯定会导致代码不可读且不可维护,因为我在always中包含的每个新输出都必须包含在所有{{1}中阻止。

然后,我的问题是:我是否必须明确为我在特定if-else块中未使用的所有输出分配值。对于未在组合if-else块中更新的信号,不存在类似“默认值”的内容,因此在评估always块后,所有未分配的输出都将恢复为默认值,或者“不关心” “价值?

到目前为止,我已经采用了这种解决方法,这似乎有效:

always

但是我想要一些更优雅的东西,就像Verilog 2001处理组合module ifelse( input wire a, input wire b, input wire c, input wire d, output reg y1, output reg y2, output reg y3 ); always @* begin // default values y1 = 1'bx; y2 = 1'bx; y3 = 1'bx; if (a==1'b1 && b==1'b0) begin y1 = 1'b0; y3 = 1'b1; end else if (a==1'b0 && c==1'b1 && d==1'b0) begin y2 = 1'b1; y1 = 1'b1; end else if (a==1'b0 && c==1'b0) begin y3 = 1'b0; y2 = 1'b0; end end endmodule 的敏感度列表一样,就像这样:

always

因此,如果我修改此module ifelse( input wire a, input wire b, input wire c, input wire d, output reg y1, output reg y2, output reg y3 ); always @* begin if (a==1'b1 && b==1'b0) begin y1 = 1'b0; y3 = 1'b1; end else if (a==1'b0 && c==1'b1 && d==1'b0) begin y2 = 1'b1; y1 = 1'b1; end else if (a==1'b0 && c==1'b0) begin y3 = 1'b0; y2 = 1'b0; end @* = x; // unassigned outputs receive a default value of "dont care" end endmodule 以添加仅在几个块中更新的新输出,我不必在“默认”块中包含它,同样的方式我不必将其包含在敏感度列表中。

那么,Verilog中是否存在这样的功能?实际上我的解决方法是这样做的,还是有更优雅的解决方案?

非常感谢:)

1 个答案:

答案 0 :(得分:4)

执行此操作的方法是在第一个reg语句之前的begin开始块之后,为每个if分配一个默认值。如果你打算合成它,你不能将1'bx分配给一个信号......你期望得到什么样的硬件?请记住,信号上出现的x是未知值,而不是无关紧要的情况。

相关问题