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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вывод Multiport Switch с больше, чем 1024 входные параметры.

Если вы задаете больше, чем 1024 входные параметры с блоком Multiport 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


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

Функции

Похожие темы