-1

Hi why is it that VCS simulation allows for some assignments from 2 different always block, while for some others it is not allowed

In the code below: While compiling with the variable pass_val but without rollover_n the compile and run of the code seems fine. No issue

However when I introduced rollover_n as seen in the code below, I get the compiler error "illegal combination of procedural drivers", pointing that rollover_n is assigned in 2 different always block.

Both of these rollover_n and pass_val are assigned values in 2 different always block, but rollover_n gets an error message, while pass_val is allowed

here is the pseudocode :


input power
input[47:0] input_array
logic [11:0] slice[3:0]
logic [11:0] moving_comparator 
logic [11:0] pass_val

initial
slice[3:0] = {0,0,0,0};
moving_comparator = 0;
pass_val = 0;:


//bit slicing block
always_comb begin
  if(enable[0]==1 && power==1)
    slice[0] = input_array[11:0];
  else if (power==0)
    slice[0] = 0;
  if(enable[1]==1 && power==1)
    slice[1] = input_array[23:12];
  else if (power==0)
    slice[1] = 0;
  if(enable[2]==1 && power==1)
    slice[2] = input_array[35:24];
  else if (power==0)
    slice[2] = 0;
  if(enable[3]==1 && power==1)
    slice[3] = input_array[47:36];
  else if (power==0)
    slice[3] = 0;

  foreach(slice[i])begin
    if(moving_comparator<slice[i] && power==1)moving_comparator = slice[i];
    else if (power==0) moving_comparator = 0;
  end 
    pass_val = moving_comparator;
    if(pass_val == 0 && ((|enable) == 1)) rollover_n = 1;//~(|moving_comparator) ;// just to trigger the arbitration block in case assignment to pass_val is actually 0
    else seqnum_rollover_n = 0;
    foreach(slice[i])begin //IMPORTANT!! make sure moving comparator dont compare with stale values from prev selects
        slice[i] = 0;
    end
    moving_comparator = 0;
end 

//arbitration block 
always @(pass_val,compare,rollover_n) begin
  if(pass_val>compare)begin output=pass_val;
    pass_val = 0;
  end
  else begin 
    output=compare;
  end

  if(rollover_n) begin 
    rollover_n = 0;
 end 
end

So, why is it that pass_val is allowed to be assigned values in

always @(pass_val,compare,rollover_n) and always_comb but rollover_n is not

  • your code contains too many syntactic issues and cannot be compiled. you need to fix them and re-post your code. It makes no sense to look at it in this state. – Serge May 31 '19 at 01:17
  • i did not mean for the code snippet to be compiled, just wondering why in certain condition multiple driver is allowed and others not, I also had to change the variable names for privacy reasons. – TheSprintingEngineer May 31 '19 at 08:39
  • simulation allows multiple register drivers for v95/v2k always blocks. Synthesis can break though. Standard does not allow multiple drivers for system verilog blocks (always_comb/latch/ff). Some compilers (i.e., vcs) do check for this condition at compilation time. They do not allow mix of driving across different procedural blocks which also includes sv blocks. i.e. always_comb and initial. If you want multiple drivers, stay away from sv always blocks and be aware of consequences. – Serge May 31 '19 at 13:46

1 Answers1

0

I copied your code and ran it with some typos fixed (missing semi-colons in the inputs definitions and added begin/end to initial block. I get an error for both nets.

Parsing design file 'test.sv' Top Level Modules: test No TimeScale specified

Error-[ICPD] Illegal combination of drivers test.sv, 8
Illegal combination of procedural drivers
Variable "pass_val" is driven by an invalid combination of procedural drivers. Variables written onleft-hand of "always_comb" cannot be written
to by any other processes, including other "always_comb" processes.
This variable is declared at "test.sv", 8: logic [11:0] pass_val;
The first driver is at "test.sv", 60: pass_val = 0;
The second driver is at "test.sv", 25: always_comb begin if ((enable[0] == 1'b1) && (power == 1'b1)) begin ...

Error-[ICPD] Illegal combination of drivers test.sv, 13 Illegal combination of procedural drivers
Variable "rollover_n" is driven by an invalid combination of procedural drivers. Variables written on left-hand of "always_comb" cannot be written
to by any other processes, including other "always_comb" processes. This variable is declared at "test.sv", 13: logic rollover_n;
The first driver is at "test.sv", 67: rollover_n = 0;
The second driver is at "test.sv", 25: always_comb begin if ((enable[0] == 1'b1) && (power == 1'b1)) begin ...

2 errors CPU time: .066 seconds to compile

Charles Clayton
  • 17,005
  • 11
  • 87
  • 120
  • very curious, this code snippet is actually a part of an already running code, i just changed the variable names for privacy reasons, but for sure the `pass_val` variable's multiple assignment did not cause an error in my compilation and running code – TheSprintingEngineer May 31 '19 at 08:36
  • Hmm, I suspect that the net `pass_val` has been optimized out in synthesis earlier in the compilation stage so it doesn't come up. – Charles Clayton May 31 '19 at 17:51