exponenta event banner

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

Импорт HDL используется для импорта синтезируемого кода 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    
    
  

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

Например, этот код Verilog выполняет множественные назначения переменной out1 внутри условий if и else блока always.


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    
    
  
Операции выбора битов, выбора деталей и индексации массива с сигналами. Мультипортовый коммутатор выводится при выполнении индексации массива в 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.

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

Например, при импорте этого кода Verilog условие if выводится как блок 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 в качестве RAMs. Эта конструкция не поддерживается. Разделите каждый вывод ОЗУ на один модуль.


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


См. также

Функции

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

Подробнее