Моделирование Verilog Dataflow с импортом HDL

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

В этих таблицах перечислены поддерживаемые Verilog® HDL- шаблонов dataflow, которые можно использовать при импорте HDL-кода. Если ваш код использует неподдерживаемую модель dataflow, такую как код, который выводит защелку, importhdl генерирует сообщение об ошибке со ссылкой на имя файла и номер линии. Затем можно обновить код, как показано в предыдущих примерах.

Поддерживаемые шаблоны Verilog Dataflow

Модель Verilog DataflowПример кода Verilog

Назначения блокировки в последовательных всегда блоках и назначения без блокировки в комбинационных всегда блоках.

Например, этот код 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

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

В этом примере показан код Verilog, который выполняет как частичное присвоение, так и полное присвоение переменной 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    
    
  

Несколько назначений одной и той же переменной в пути true или false блока Switch, который выводится.

Например, этот код Verilog выполняет несколько присвоений переменной out1 внутри как условий if, так и условий всегда блока.


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    
    
  
Выбор бита, выбор детали и операции индексации массива с сигналами. Выводится Multiport Switch, когда индексация массива выполняется в RHS. Операция индексации массива в LHS выводится как блок Assign.

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


module ArrayIndexing 
    (In1, In2, In3, In4, 
    Sel1, Sel2, 
    Out1, Out2, Out3);

parameter w = 7;
input  [w:0] In1, In2, In3, In4;
input  [1:0] Sel1, Sel2;
output [w:0] Out1;
output [1:0] Out2;
output       Out3;

wire [w:0] v[3:0];

assign v[0] = In1;
assign v[1] = In2;
assign v[2] = In3;
assign v[3] = In4;

//Array indexing with signal Sel1
assign Out1 = v[Sel1];

//Part select on array index with signal Sel2
assign Out2 = v[Sel2][7:2];

//Bit select on array index with signal Sel
assign Out3 = v[Sel2][4];

endmodule

Неподдерживаемые шаблоны Verilog Dataflow

Эти конструкции dataflow не поддерживаются при импорте кода Verilog. В столбцах Описание и Пример сценариев описывается каждый сценарий с помощью примера и показано, как избежать этого сценария.

Модель Verilog DataflowОписание и примеры сценариев

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

Наличие защелок в HDL-коде может привести к алгебраическим циклам в сгенерированной модели Simulink и привести к отказам компиляции модели. Чтобы избежать вывода защелки, задайте все ветви в условиях if-else и в операторах case.

Для примера при импорте этого кода Verilog условие if выводится как Switch блок. Блок имеет истинный путь, который задан в коде. Выход блока Switch передается назад непосредственно как вход в ложный путь, который приводит к алгебраическому циклу.


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

// causes latch inference - unsupported
always@(*) begin
    if (cond) begin
        out1 = in1;
    end
end

// Specify else branch to avoid latch inference
// always@(*) begin
//     if (cond) begin
//         out1 = in1;
//     end
//     else begin
//         out1 = in1 + 1;
//     end
// end

endmodule

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

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

Для примера этот код 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 выводит sample_store0 и sample_store1 как ОЗУ. Эта конструкция не поддерживается. Разделите каждый вывод ОЗУ на один модуль.


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    
    
  

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

Система координат initial блок не поддерживает конструкции, отличные от операторов назначения, или циклы с назначениями. RHS оператора назначения должен использовать только

Например, этот код Verilog использует условие if-else, чтобы присвоить значение переменной dout_a и присваивает переменную write_data на dout_c, которые не поддерживаются.

module testInitial 
        (input cond, 
        input [3:0] write_data
        output reg [3:0] dout_a, dout_b, doutc);
        
        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-else condition - not supported
          if (cond) begin
               dout_a = 0;
          end
          else begin
               dout_a = 4;
          end
          end
          
          // Variable assignment to RHS - not supported
          dout_a = write_data;

          // Use assignment statements instead for 
          // dout_a and dout_c 
          // dout_a = 4;
          // dout_c = 32;
          // end
          // end
          
endmodule  


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

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

Для примера этот код Verilog создает 8-bit переменная 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];

// temp_reg is not indexed 
// with both dimensions - not supported
always @(posedge clk) begin
        temp_reg [0] <= a[0] + b[0];
        temp_reg [1] <= a[1] + b[1];
    end


// Use both dimensions when indexing a variable
// 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];

// You can also perform indexed bit select
//         temp_reg [1][0][1] = 1'b0;
//  end

assign c = temp_reg;

endmodule


См. также

Функции

Похожие примеры

Подробнее о