SV: Ошибка легальной комбинации процессуальных драйверов - PullRequest
0 голосов
/ 01 апреля 2020

Получение ошибки SV: Error illegal combination of procedural drivers с приведенным ниже кодом, есть идеи, как решить эту проблему? Значения температуры варьируются от 0 до 3.

    module multi_driver_check ();
    reg [7:0] ll_data_map[3:0];
    reg [7:0] data_in[3:0];
    reg [7:0] temp[3:0];
    assign data_in = '{default:0};
    genvar map_i;
    for(map_i=0;map_i<4;map_i++)
    begin
      always_comb
      begin
        if(temp[map_i]==0)
          ll_data_map[0] = data_in[map_i];
        else if(temp[map_i]==1)
          ll_data_map[1] = data_in[map_i];
        else if(temp[map_i]==2)
          ll_data_map[2] = data_in[map_i];
        else
          ll_data_map[3] = data_in[map_i];
     end 
    end
   endmodule

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Причина ошибки:
Генерация для -l oop обнаруживает код, который он инкапсулирует в нем во время разработки компиляции. always_comb убедитесь, что все, что он назначает, не назначено где-либо еще. В вашем скомпилированном коде у вас фактически есть 4 always_comb s, присваивающие ll_data_map, что недопустимо.

Решение:
Переместите for-l oop внутрь always_comb (map_i не может быть genvar). Таким образом, все присвоения ll_data_map выполняются одним always_comb.

Другое Примечание:
ll_data_map не является комбинационной логикой c, даже если бы она считалась определенный в always_comb. Лучшие инструменты отметят это; в худшем случае его не удастся синтезировать, потому что целевые устройства не поддерживают защелки.
Чтобы сделать это правильной комбинационной логикой c, вы можете добавить ll_data_map = '{default:'0}; (или какое-либо другое определяющее назначение c) перед запуском for- l oop.
Если ll_data_map предназначена для защелки, используйте always_latch вместо always_comb. (В общем дизайне RTL защелки не рекомендуется, но они необходимы для определенных функций)

0 голосов
/ 01 апреля 2020

генерировать оператор просто дублирует или условно добавляет / исключает оператор в своем теле. В вашем случае он генерирует несколько блоков always_comb, как показано ниже:

always_comb
      begin
        if(temp[0]==0)
          ll_data_map[0] = data_in[0];
        else if(temp[0]==1)
          ll_data_map[1] = data_in[0];
        else if(temp[0]==2)
          ll_data_map[2] = data_in[0];
        else
          ll_data_map[3] = data_in[0];
     end
always_comb
      begin
        if(temp[1]==0)
          ll_data_map[0] = data_in[1];
        else if(temp[1]==1)
          ll_data_map[1] = data_in[1];
        else if(temp[1]==2)
          ll_data_map[2] = data_in[1];
        else
          ll_data_map[3] = data_in[1];
     end

...

, как вы можете видеть, ll_data_map[0] (и другие) приводятся как минимум 4 раза из разных блоков всегда. Это недопустимо.

Я предполагаю, что вам не нужен какой-либо блок генерации здесь, а просто нужно переместить ваш для l oop внутри блока Always:

int map_i;
always_comb begin
  for(map_i=0;map_i<4;map_i++)
    begin
        if(temp[map_i]==0)
          ll_data_map[0] = data_in[map_i];
        else if(temp[map_i]==1)
          ll_data_map[1] = data_in[map_i];
        else if(temp[map_i]==2)
          ll_data_map[2] = data_in[map_i];
        else
          ll_data_map[3] = data_in[map_i];
     end 
 end



...