Ограничения импорта HDL Verilog

Используйте HDL import, чтобы импортировать синтезируемый HDL-код в среду моделирования Simulink®. Чтобы импортировать HDL-код, используйте функцию importhdl.

Эта таблица показывает ограничения импорта HDL и построений Verilog, которые не поддержаны при импорте HDL-кода.

Неподдерживаемые построения или ограниченияОписание и сценарии в качестве примераРабота вокруг

Импорт файлов VHDL.

Импорт файлов Verilog от папки только для чтения.

Импорт файлов HDL, которые используют неподдерживаемые построения Verilog.

Используйте подмножество построений Verilog, которое поддерживается импортом HDL. Чтобы узнать больше, смотрите Поддерживаемые Построения Verilog для Импорта HDL.

Генерация файлов предварительной обработки в файловой системе только для чтения, которые анализируют HDL-код, который вы вводите к функции importhdl.

Припишите экземпляры и комментарии, которые проигнорированы.

(#) задерживают значения, такие как #25, которые проигнорированы.

Типы данных перечисления.

Больше чем один сигнал часов.

Модули, которые являются многоскоростными.

Многопортовый вывод Переключателя с больше, чем входными параметрами 1024.

Если вы задаете больше, чем входные параметры 1024 к Многопортовому блоку switch, который выведен из кода Verilog, импорт Verilog генерирует ошибку. Ошибка сгенерирована, потому что среда моделирования Simulink не поддерживает больше, чем входные параметры 1024 для блока.

Обнаружение ROM из кода Verilog.

Фиксируйте обнаружение.

Присутствие фиксаторов в HDL-коде может привести к алгебраическим циклам в сгенерированной модели Simulink и привести к образцовым отказам компиляции.

Например, когда вы импортируете этот код Verilog, если-условие выведено как блок switch. Блок имеет истинный путь, который задан в коде. Вывод блока switch возвращен непосредственно, как введено к ложному пути, который приводит к алгебраическому циклу.


module testAlgebraicLoop(input cond,
        input [2:0] in1,
        output reg [2:0] out1);

always@(*) begin
    if (cond) begin
        out1 = in1;
    end
end

endmodule

Чтобы избежать вывода фиксатора, задайте все ответвления в если еще условия и в случае, если операторы.


module testAlgebraicLoop(input cond,
        input [2:0] in1,
        output reg [2:0] out1);

always@(*) begin
    if (cond) begin
        out1 = in1;
    end
    else begin
        out1 = in1 + 1;
    end
end

endmodule

Частичное и полное присвоение на ту же переменную в коде Verilog®.

Этот пример показывает код Verilog, который выполняет и частичное присвоение и полное присвоение на переменную out1_reg.

Код использует частичное присвоение на переменную out1_reg в истинном ответвлении если-условия и полное присвоение на out1_reg в

Это построение не поддержано. Импорт кода генерирует ошибку.


module testPartialAndCompleteAssign
    (input [2:0] in1, in2,
     input cond, clk,
     output [2:0] out1);
  
  reg [2:0] out1_reg;
  
  always@(posedge clk) begin
    if(cond) begin
      out1_reg[0] = 1'b0;
      out1_reg[1] = 1'b0;
      out1_reg[2] = 1'b0;
    end
    else begin
      out_reg = in1 & in2;
    end
  end
  assign out1 = out1_reg;

endmodule    
    
  

Когда вы присвоите одну переменную, используйте или полное присвоение или частичное присвоение.

Например, этот код показывает, как можно изменить пример, чтобы выполнить полное присвоение на переменную out1_reg. Это построение Verilog поддерживается.


module testCompleteAssign
    (input [2:0] in1, in2,
     input cond, clk,
     output [2:0] out1);
  
  reg [2:0] out1_reg;
  
  always@(posedge clk) begin
    if(cond) begin
      out1_reg = 3'd0;
    end
    else begin
      out_reg = in1 & in2;
    end
  end
  assign out1 = out1_reg;

endmodule    
    
  

Этот пример показывает другой код Verilog, который выполняет частичное присвоение на переменную out1_reg. Это построение также поддержано.


module testPartialAssign
    (input [2:0] in1, in2,
     input cond, clk,
     output [2:0] out1);
  
  reg [2:0] out1_reg;
  
  always@(posedge clk) begin
    if(cond) begin
      out1_reg[0] = 1'b0;
      out1_reg[1] = 1'b0;
      out1_reg[2] = 1'b0;
    end
    else begin
      out_reg[0] = in1[0] & in2[0];
      out_reg[1] = in1[1] & in2[1];
      out_reg[2] = in1[2] & in2[2];
    end
  end
  assign out1 = out1_reg;

endmodule    
    
  
При выполнении операций на часах сброс или часы включает сигналы в коде Verilog.

Когда вы задаете сигналы с помощью имен, таких как clk, rst и enb, импорт HDL выводит эти сигналы быть часами, глобальным сбросом, и часы включают сигналы.

Например, этот код Verilog использует явное присвоение с сигналом часов clk. Это построение не поддержано.


module testOperationOnClkBundle
    (input [2:0] in1,
     input clk,
     output reg [2:0] out1,
     output out2);
  
  reg [2:0] out1_reg;
  
  always@(posedge clk) begin
     out1_reg <= in1;
    end
 
  assign out2 = clk && 1'b1;

endmodule    
    
  

Убедитесь, что ваш код Verilog не выполняет операции ни на одном из сигналов в пакете часов.

Для сигналов, что вы используете для выполнения вычислений в вашем коде, убедитесь, что имена сигнала не совпадают ни с одним из имен, которые выведены как часы, сбрасывают или включают сигналы. Смотрите пару "имя-значение" clockBundle функции importhdl для возможных имен сигнала, которые выведены как сигналы в пакете часов.

Чувствительность часов или сброса сигнализирует к различным фронтам синхроимпульса или различным ребрам сброса в том же модуле.

Это означает, что у вас не может быть одного блока always с сигналом часов, чувствительным к положительному ребру, и другой блок always с часами сигнализируют чувствительный к отрицательному ребру в том же модуле.

Например, этот код Verilog использует два других края тех же часов, которые не поддержаны.


module testMultipleClockEdges
    (input [2:0] in1, in2,
     input clk,
     output [2:0] out1, out2);
  
  reg [2:0] out1_reg, out2_reg;
  
  /* clk sensitivity to posedge */
  always@(posedge clk) begin
     out1_reg <= in1 && in2;
    end
  
  /* clk sensitivity to neegedge */
  always@(negedge clk) begin
     out2_reg <= in1 || in2;
    end
  
  assign out1 = out1_reg;
  assign out2 = out2_reg;

endmodule    
    
  

Убедитесь, что ваш код Verilog не использует оба ребра часов или сигнала сброса в том же модуле. Используйте или posedge или negedge часов.

Реализация синхронных и асинхронных схем в том же модуле.

Например, этот код Verilog понимает обе схемы в том же модуле.


module testSynchronousAsynchronous
    (input [2:0] in1, in2,
     input clk, reset,
     output [2:0] out1, out2);
  
  reg [2:0] out1_reg, out2_reg;
  
  /* synchronous always block */
  always@(posedge clk) begin
     out1_reg <= in1 && in2;
    end
  
  /* asynchronous always block */
  always@(posedge clk or posedge reset) begin
     out2_reg <= in1 || in2;
    end
  
  assign out1 = out1_reg;
  assign out2 = out2_reg;

endmodule    
    
  

Убедитесь, что ваш код Verilog понимает или асинхронные схемы или схемы синхронизации в том же модуле.

Инициализация нескольких RAM, которые выведены в том же модуле.

Например, этот код Verilog выводит sample_store0 и sample_store1 как RAM. Это построение не поддержано.


module testMultipleRAMs
    (input [2:0] in1, in2,
     input clk, reset,
     output reg [2:0] read_data0, read_data1);
  
  reg [2:0] out1_reg, out2_reg;
  
  /* Inference of RAM sample_store0 */
  always@(posedge clk) begin
    if (write_enable) begin
      sample_store0[write_address] <= write_data;
    end
    read_data0 = sample_store0[read_address0]
  end
  
  /* Inference of RAM sample_store1 */
  always@(posedge clk) begin
    if (write_enable) begin
      sample_store1[write_address] <= write_data;
    end
    read_data1 = sample_store0[read_address1]
  end
  
endmodule    
    
  

Убедитесь, что ваш код Verilog не выводит больше чем один RAM в том же модуле. Можно разделить каждый вывод RAM на один модуль.

Несколько присвоений на ту же переменную в истинном или ложном пути блока switch, который выведен.

Например, этот код Verilog использует несколько присвоений на переменную out1 в ложном ответвлении, которое не поддержано.


module testSwitchMuxing
    (input [2:0] in1,
     input cond,
     output reg [2:0] out1);
  
  always@(*) begin
      if (cond) begin
          out1 = in1;
      end
      else begin
          out1 = 3'd2;
          out1 = 3'd1;
      end
   end
  
endmodule    
    
  

Убедитесь, что ваш код Verilog не использует больше чем одно присвоение на ту же переменную в том же пути если-условия. Можно присвоить значения той же переменной в различных ответвлениях.

Использование определенных построений при чтении начальных значений из блока initial.

Блок initial не поддерживает построения кроме операторов присваивания или циклов for с присвоениями. Например, этот код Verilog использует, если еще условие присвоить значение переменной dout_a, которая не поддержана.


module testInitial (input cond,
         output reg [3:0] dout_a, dout_b);
        
        parameter AddrWidth = 3;
        
        integer i;
        reg [3:0] ram [7:0]; 
        
        initial begin
          for (i=0; i<=2**AddrWidth - 1; i=i+1) begin
              ram[i] = 0;
          end
          dout_b = 0;
          if (cond) begin
               dout_a = 0;
          end
          else begin
               dout_a = 4;
          end
        end
        
endmodule  


Блок initial поддерживает только константы или постоянные присвоения в RHS. Например, этот код Verilog присваивает переменную write_data dout_a, который не поддержан.


module testInitial (input [3:0] write_data,
         output reg [3:0] dout_a, dout_b);
        
        parameter AddrWidth = 3;
        
        integer i;
        reg [3:0] ram [7:0]; 
        
        initial begin
          for (i=0; i<=2**AddrWidth - 1; i=i+1) begin
              ram[i] = 0;
          end
          dout_b = 0;
          dout_a = write_data;
          end
        end
        
endmodule  

Убедитесь, что initial блокируется в вашем коде Verilog:

  • Используйте только операторы присваивания и циклы for с присвоениями.

  • Используйте только постоянные значения или константные выражения в RHS.


module testInitial (
         output reg [3:0] dout_a, dout_b);
        
        parameter AddrWidth = 3;
        
        integer i;
        reg [3:0] ram [7:0]; 
        
        initial begin
          for (i=0; i<=2**AddrWidth - 1; i=i+1) begin
              ram[i] = 0;
          end
          dout_b = 0;
          dout_a = 0;
          end
        
endmodule
          
 
Неблокирование присвоений в комбинационном always блокируются и блокирование присвоений в последовательных блоках always.

Импорт HDL выводит схему комбинационной или последовательной логики в зависимости от списка чувствительности блока always.

Например, этот код Verilog использует последовательное присвоение для переменной temp в комбинационном блоке always, который не поддержан.


module dataconv(clk,a,b,c);

input clk; integer i;
input wire [7:0] a, b;
output wire [7:0] c;
reg [1:0] temp [0:7];

always @(*) begin
    for (i=0;i<=7;i=i+1) begin
        temp[i] <= a[i] + b[i];
    end
 end

assign c = temp;

endmodule


Убедитесь, что тип присвоения совпадает с типом схемы, выведенным блоком always.


module dataconv(clk,a,b,c);

input clk; integer i;
input wire [7:0] a, b;
output wire [7:0] c;
reg [1:0] temp [0:7];

//Proposed change 1: change assignment to blocking.
always @(*) begin
    for (i=0;i<=7;i=i+1) begin
        temp[i] = a[i] + b[i];
    end
 end

//Proposed change 2: change circuit type to sequential
// always @(posedge clk) begin
//    for (i=0;i<=7;i=i+1) begin
//        temp[i] <= a[i] + b[i];
//    end
// end

assign c = temp;

endmodule


Все размерности сигналов, на которые не ссылаются во время использования.

Например, этот код Verilog создает 8-битную переменную temp. Присвоение в блоке always генерирует ошибку, потому что это не использует обе размерности переменной.


module dataconv(clk,a,b,c);

input clk; 
input wire [1:0] a, b;
output wire [1:0] c;

reg [7:0] temp_reg [1:0][1:0];

always @(posedge clk) begin
        temp_reg [0] <= a[0] + b[0];
        temp_reg [1] <= a[1] + b[1];
    end

assign c = temp;

endmodule


Убедитесь, что все размерности сигнала используются в коде входа Verilog. Если вы задаете дополнительную размерность, она создает индексируемый битный выбор.


module dataconv(clk,a,b,c);

input clk; 
input wire [2:0] a, b;
output wire [2:0] c;

reg [7:0] temp_reg [2:0][2:0];

always @(posedge clk) begin
        temp_reg [0][0] <= a[0] + b[0];
        temp_reg [0][1] <= a[0] + b[1];
        temp_reg [1][0] <= a[1] + b[0];
        temp_reg [1][1] <= a[1] + b[1];

        // This code performs an indexed bit select
        // temp_reg [1][0][1] = 1'b0;
    end

assign c = temp;

endmodule


Смотрите также

Функции

Похожие темы