Illegal operand for constant expression

user3570982 picture user3570982 · Jan 8, 2015 · Viewed 11.5k times · Source

I'm trying to build a task, which must delve into some hierarchy, that can concisely compare different pins on a particular instance. In particular, I'd like to do something like the following:

task check_expected;
  input integer pin;
  input [9:0] expected;
  integer i, j;
  reg [9:0] check;
  begin
    j = 0;

    for (i = 0; i < 20; i = i + 1) begin
      case (pin)
        0: begin
          check[0] = test.inst[i].lane_0.PIN_FIRST;
          check[1] = test.inst[i].lane_1.PIN_FIRST;
          ...
          check[9] = test.inst[i].lane_9.PIN_FIRST;
        end
        1: begin
          check[0] = test.inst[i].lane_0.PIN_SECOND;
          check[1] = test.inst[i].lane_1.PIN_SECOND;
          ...
          check[9] = test.inst[i].lane_9.PIN_SECOND;
        end
        ...
        9: begin
          check[0] = test.inst[i].lane_0.PIN_TENTH;
          check[1] = test.inst[i].lane_1.PIN_TENTH;
          ...
          check[9] = test.inst[i].lane_9.PIN_TENTH;
        end
      endcase

      if (check[0] !== expected[j*10 + 0]) begin
        TEST_FAILED = TEST_FAILED + 1;
        $display("ERROR Expected=%b,  @ %0t",expected[j*10 + 0],$time);
      end
      if (check[1] !== expected[j*10 + 1]) begin
        TEST_FAILED = TEST_FAILED + 1;
        $display("ERROR Expected=%b,  @ %0t",expected[j*10 + 1],$time);
      end
      ...
      if (check[9] !== expected[j*10 + 9]) begin
        TEST_FAILED = TEST_FAILED + 1;
        $display("ERROR Expected=%b,  @ %0t",expected[j*10 + 9],$time);
      end
    end
  end
endtask

Unfortunately, attempting to do the above throws a NOTPAR error during elaboration, claiming that it is unacceptable to assign a register to a non-constant (it doesn't like any lines like check[0] = test.inst[i].lane_0.PIN_FIRST;). This is just for testing purposes, not anything synthesizeable, by the way.

Can someone explain why this is disallowed and suggest a different solution? It's looking like I'll need to write a task for each and every loop iteration, and that seems like it would be needlessly bloated and ugly.

Thanks

Answer

user3570982 picture user3570982 · Jan 8, 2015

To answer my own question, the answer is that there is no way to do it with Verilog. Verilog is an incredibly dumb (in terms of capabilities) language, and, with a task, can only support constant indices for module instances. No looping is possible.