如何在组合 always 块中为输出分配默认值,以便即使使用不完整的 if-else 语句也不会推断出锁存器 [英] How to assign default values to outputs in a combinational always block so latches are not inferred even if incomplete if-else statements are used

查看:31
本文介绍了如何在组合 always 块中为输出分配默认值,以便即使使用不完整的 if-else 语句也不会推断出锁存器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say I want to write a combinational module that uses 4 inputs and 3 outputs. To model my logic, I do something like this:

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 分配一个值,如下所示:

Ok, I'm aware that this code will infer latches for y1,y2 and y3, and the way to go to avoid this is to assign always a value to every LHS in every if-else block, like this:

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 中包含的每个新输出都会有包含在所有 if-else 块中.

But now, imagine that there are a lot of if-else blocks (I'm trying to describe the control unit for a didactic microprocessor) and that there are a lots of outputs coming from this module (the control lines for all the registers in the data path of the microprocessor). Having to assign a value to every output in every if-else block will surely lead to an unreadable and unmaintenable code, as every new output I include in this always, will have to be included in all if-else blocks.

然后,我的问题是:我是否必须为我没有在特定 if-else 块中使用的所有输出明确分配一个值.对于在组合 always 块中未更新的信号,是否有类似默认值"之类的东西,以便在评估 always 块后,所有未分配的输出都恢复为默认值价值,还是不在乎"的价值?

Then, my question is: Do I have to explicity assign a value for all outputs I'm not using in a particular if-else block. Isn't there something like a "default value" for signals not updated in an combinational always block, so that after evaluating the always block, all unassigned outputs revert to a default value, or "dont care" value?

到目前为止,我已经提出了这个解决方法,它似乎有效:

So far, I've come with this workaround, that seems to works:

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

但我想要更优雅的东西,就像 Verilog 2001 处理组合 always 的敏感度列表一样,像这样:

But I'd like something more elegant, much in the same way Verilog 2001 handles the sensitivity list for combinational always, something like this:

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

这样,如果我修改此 always 以添加仅在几个块中更新的新输出,我不必将它也包含在默认"块中,与我不必将其包含在敏感列表中的方式相同.

So that if I modify this always in order to add a new output that is updated only in a few blocks, I don't have to include it as well in the "default" block, the same way I don't have to include it in the sensitivity list.

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

So, does such feature exist in Verilog? Is actually my workaround the way to do this, or is there a more elegant solution?

非常感谢:)

推荐答案

这样做的方法是在 begin 之后为每个 reg 分配一个默认值在第一个 if 语句之前启动块.如果您打算合成信号,则不能将 1'bx 分配给它……您希望获得什么样的硬件?请记住,出现在信号上的 x 是一个未知值,而不是无关紧要的条件.

The way to do this is to assign a default value to every reg just after the begin that starts the block, before the first if statement. You can't assign 1'bx to a signal if you intend to synthesize it...what kind of hardware would you expect to get? Remember that an x appearing on a signal is an unknown value, not a don't-care condition.

这篇关于如何在组合 always 块中为输出分配默认值,以便即使使用不完整的 if-else 语句也不会推断出锁存器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆