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

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

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

Поддерживаемые шаблоны потока данных Verilog

Модель потока данных VerilogПример код 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    
    
  

Несколько присвоений на ту же переменную в истинном или ложном пути блока 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    
    
  
Битный выбор, выбор части и операции индексации массива с сигналами. Multiport Switch выведен, когда индексация массива выполняется в RHS. Операция индексации массива на LHS выведена как блок Assign.

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


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

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

Модель потока данных VerilogОписание и сценарии в качестве примера

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

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

Например, когда вы импортируете этот код Verilog, если-условие выведено как блок 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, и 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    
    
  

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

Например, этот код Verilog выводит sample_store0 и sample_store1 как RAM. Это построение не поддерживается. Разделите каждый вывод 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    
    
  

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

initial блок не поддерживает построения кроме операторов присваивания или циклов for с присвоениями. RHS оператора присваивания должен использовать только

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


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

Функции

Связанные примеры

Больше о