将在always_comb中的临时变量创建闩锁

时间:2018-07-02 02:49:57

标签: verilog system-verilog

我有以下代码片段,其中使用了一个temp变量来计算数组中1的数量:

   // count the number 1s in array 
   logic [5:0] count_v; //temp
   always_comb begin
      count_v = arr[0];
      if (valid) begin
         for (int i=1; i<=31; i++) begin
            count_v = arr[i] + count_v;
         end
      end
      final_count = count_v;
   end

此逻辑会为count_v创建一个锁存器吗?综合工具足够聪明,可以正确地综合此逻辑吗?我正在努力寻找针对此类情况的任何编码建议。

另一个例子:

logic temp; // temp variable
always_comb begin
   temp = 0;
   for (int i=0; i<32; i++) begin
      if (i>=start) begin
         out_data[temp*8 +: 8] = in_data[i*8 +: 8];
         temp = temp + 1'b1;
      end
   end
end

3 个答案:

答案 0 :(得分:0)

一般规则:如果在写入变量之前先读取了变量,则您的代码暗含某种内存。在这种情况下,模拟器和合成器都必须实现先前值的存储,因此合成器将为您提供寄存器或锁存器。您的两个示例都在读取临时文件之前先将其写入临时文件,因此没有暗示存储空间。

是综合吗?试试看。我已经在生产代码中看到了很多类似的东西,并且它可以工作(与我使用的合成器一起使用),但是我自己却不这样做。我会尝试一下,看看会创建什么逻辑,然后使用它来决定是否需要考虑更多逻辑。无需循环即可轻松计数设置位,但是count循环几乎可以肯定会与您的合成器一起使用。第二个示例可能会有更多问题。

答案 1 :(得分:0)

对于任何具有确定性初始分配的Always块,除逻辑循环外,它将不会生成锁存器。

答案 2 :(得分:0)

对不起,尤迪,我们似乎正在就您的帖子进行一些讨论。

这是一些示例代码:

module latch_or_not (
   input            cond,
   input      [3:0] v_in,
   output reg       latch,
   output reg [2:0] comb1,
   output reg [2:0] comb2

   );

reg [2:0] temp;
reg [2:0] comb_loop;

  // Make a latch
  always @( * )
     if (cond)
        latch = v_in[0];

  always @( * )
  begin : aw1
     integer i;
     for (i=0; i<4; i=i+1)
       comb_loop = comb_loop + v_in[i];
     comb2 = comb_loop;
  end

  always @( * )
  begin : aw2
     integer i;
     temp = 7;
     for (i=0; i<4; i=i+1)
       temp = temp - v_in[i];
     comb1 = temp;
  end

endmodule

如果根据精心设计的Xilinx Vivado工具得出的结果如下:

“闩锁”输出显而易见。您还将注意到最终结果中不存在温度。

'comb_loop'不是锁存器,而是更糟糕的是:它是组合循环。逻辑的输出返回到输入。绝对不行!

enter image description here