Question

I have written the following working code to calculate an enable signal.

logic            l_en [0:N-1];
logic    [0:N-1] l_output_grant [0:M-1];

always_comb begin
  for (int i=0; i<N; i++) begin
    l_en[i]   = |{l_output_grant[0][i], 
                  l_output_grant[1][i], 
                  l_output_grant[2][i], 
                  l_output_grant[3][i], 
                  l_output_grant[4][i]};
  end
end

I am now trying to change the code to parameter the [0] through [4]. I tried the following code

logic            l_en [0:N-1];
logic    [0:N-1] l_output_grant [0:M-1];

always_comb begin
  for(int i=0; i<N; i++) begin
    for(int j=0; j<M; j++) begin
      l_en[i]   = |l_output_grant[j][i]; 
    end
  end
end

Which doesn't work. I assume this is because it recalculates with each iteration of j and thus clears the enable assigned by [j][i] if [j+1][i] is low.

What other ways could I do this please?

Was it helpful?

Solution

l_en[i] = |l_output_grant[j][i] overrides the previews assignment. Also, |l_output_grant[j][i] is a bit-wise or operator to a signal bit, which does nothing.

For the desired functionality use the |= bit-wise operator; l_en |= l_output_grant[j]. Alternatively, use the traditional Verilog method l_en = l_en | l_output_grant[j]. Remember to clear the old values by assign l_en to all zeros before the for-loops. Failing to clear the values will create latches and prevent any high to low transition from ever happening. Since the widths match the for(i=...) loop is not needed.

always_comb begin
  l_en = '0; // all bits to zero
  for(int j=0; j<M; j++) begin
    l_en |= l_output_grant[j];
    // equivalent to: l_en[0:N-1] = l_en[0:N-1] | l_output_grant[j][0:N-1];
  end
end

Note: Use the Verilog style if the synthesizers does not support |= operator. The simulator will support the operator if SystemVerilog is supported.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top