[Из песочницы] Странности синтеза при работе с FPGA

На сегодняшний день существует два наиболее распространённых языка описания аппаратуры: Verilog/SystemVerilog и VHDL. Сами языки описания аппаратуры являются достаточно универсальными средствами, но всегда ли это так? И от чего может зависеть «не универсальность» языка описания аппаратуры?

Идея написания данной статьи возникла при синтезе одного проекта в разных средах разработки, в результате чего были получены отличные друг от друга результаты. Так как исходный модуль является достаточно объёмным, то для демонстрации полученных результатов был написан тестовый модуль меньшего объёма, но синтез которого вызывал те же предупреждения/ошибки. В качестве тестового модуля был использован 4-х битный регистр с асинхронным сбросом, а в качестве сред разработки были выбраны Libero SoC 18.1, Quartus Prime 17.1, Vivado 2017.4.1.
Сначала представлен вариант описания такого модуля на языке Verilog, текст которого воспринимается выбранными средами разработки верно:

module test1
( 
    input               clk,
    input               arst,
    input       [3:0]   data,
    output reg  [3:0]   q
);

always @( posedge clk or negedge arst ) begin
    if ( ~ arst ) begin
        q <= 4'h0 ;
    end
    else begin
        q <= data ;
    end
end

endmodule


В результате осуществления синтеза данного модуля были получены следующие схемы:

  1. Libero SoC v11.8
    test1 Libero SoC
    su2copn_99lk4jwffmboxidue-4.jpeg
  2. Quartus Prime 17.1
    test1 Quartus Prime
    5civldrmgkw5gsrcsqvkwrsttxy.jpeg
  3. Vivado 2017.4.1
    test1 Vivado
    judvnrm0awltnilsy-v6ik9sd78.jpeg


На всех синтезируемых схемах для test1 были использованы D-триггеры либо с инверсным входом сброса (Quartus Prime), либо с добавлением инвертора (VERIFIC_INV в случае Libero SoC и LUT1 в случае Vivado).

Будет ли отличаться синтезируемая схема, если изменить проверку состояния асинхронного сброса? Для этого необходимо изменить текст модуля test1 на описание модуля test2:

module test2
( 
    input               clk,
    input               arst,
    input       [3:0]   data,
    output reg  [3:0]   q
);

always @(posedge clk or negedge arst) begin
    if (arst) begin
        q<=data;    
    end
    else begin
        q<=4'h0;
    end
end

endmodule


Можно предположить, что синтез модуля test2 не должен отличаться от синтеза модуля test1, так как логики описания обоих модулей не противоречат друг другу. Однако, синтез модуля test2 привёл к следующим результатам:

  1. Libero SoC v11.8
    Синтез схемы осуществился, однако в сообщениях появилось следующее предупреждение «Edge and condition mismatch (CG136)». Данное предупреждение означает несоответствие списка чувствительности и проверки условия сброса. Однако, синтезируемая схема не отличается от модуля test1.
    test2 Libero SoC
    f1frqfolhxmrhqm-s8dh823_iwq.jpeg
  2. Quartus Prime 17.1

    Синтез схемы не осуществился с ошибкой:

    «Error (10200): Verilog HDL Conditional Statement error at test2.v (10): cannot match operand (s) in the condition to the corresponding edges in the enclosing event control of the always construct». Текст ошибки схож с предупреждением, выданным Libero SoC.

  3. Vivado 2017.4.1

    Синтез схемы осуществился с предупреждением:

    »[Synth 8–5788] Register q_reg in module test is has both Set and reset with same priority. This may cause simulation mismatches. Consider rewriting code [»/home/vlasovdv0111/project_1/project_1.srcs/sources_1/new/test2.v»:10]». Также, как и в средах Libero SoC и Quartus Prime было выдано схожее предупреждение. Кроме этого в предупреждении было сказано о возможном несоответствии итогов моделирования и работы в «железе», вследствие этого предложено переписать код модуля.

    test2 Vivado
    8ejz8dgqvtkpzwo9jf28xv2kd3a.jpeg


После описания модулей test1 и test2 появилась идея проверить, что будет, если выполнить синтез следующего кода:

module test3
( 
    input               clk,
    input               arst,
    input       [3:0]   data,
    output reg  [3:0]   q
);

always @(posedge clk or negedge arst) begin
    if (arst) begin
        q<=4'h0;
    end
    else begin
        q<=data;    
    end
end

endmodule


Описание такого регистра не является логичным, так как сброс триггеров в данном случае происходит, когда линия сброса в неактивном состоянии.

Результаты синтеза оказались следующие:

  1. Libero SoC v11.8

    Синтез схемы не осуществился с ошибкой: «Logic for q[3:0] does not match a standard flip-flop (CL123)», тем самым отказавшись производить синтез схемы, сославшись на отсутствие необходимого для синтеза типа триггеров.

  2. Quartus Prime 17.1

    Синтез схемы не осуществился со следующей ошибкой: «Error (10200): Verilog HDL Conditional Statement error at test3.v (9): cannot match operand (s) in the condition to the corresponding edges in the enclosing event control of the always construct». Текст данной ошибки не отличается от текста ошибки для модуля test2.

  3. Vivado 2017.4.1

    Синтез схемы осуществился без ошибок:

    test3 Vivado
    dkgxwe8f5hw109zv99an5h0wrha.jpeg


Однако, что будет если описать модуль, в котором список чувствительности не противоречит проверке условия сброса, но при этом сброс триггеров происходит в момент неактивного состоянии линии сброса, как и в случае описания модуля test3. Описание такого модуля test4 следующее:

module test4
( 
    input               clk,
    input               arst,
    input       [3:0]   data,
    output reg  [3:0]   q
);

always @( posedge clk or negedge arst ) begin
    if ( ~ arst ) begin
        q <= data ;
    end
    else begin
        q <= 4'h0 ;
    end
end

endmodule


При синтезе были получены следующие результаты:

  1. Libero SoC v11.8

    Синтез схемы осуществился с предупреждением:

    «Found signal identified as System clock which controls 4 sequential elements including q_1[3]. Using this clock, which has no specified timing constraint, can adversely impact design performance. (MT532)».

    test4 Libero SoC
    mselemdf578vem0b_ayoxoes5oa.jpeg
  2. Quartus Prime 17.1

    В результате синтеза схемы были получены предупреждения:

    «Warning (13004): Presettable and clearable registers converted to equivalent circuits with latches. Registers power-up to an undefined state, and DEVCLRn places the registers in an undefined state.
    Warning (13310): Register "q[0]~reg0" is converted into an equivalent circuit using register "q[0]~reg0_emulated" and latch "q[0]~1"
    Warning (13310): Register "q[1]~reg0" is converted into an equivalent circuit using register "q[1]~reg0_emulated" and latch "q[1]~1"
    Warning (13310): Register "q[2]~reg0" is converted into an equivalent circuit using register "q[2]~reg0_emulated" and latch "q[2]~1"
    Warning (13310): Register "q[3]~reg0" is converted into an equivalent circuit using register "q[3]~reg0_emulated" and latch "q[3]~1"»

    Все вышеописанные предупреждения соответствуют тому, что вместо триггеров были использованы защёлки.

    test4 Quartus Prime
    4iyz_sacasaemyg-hoykw5-cov8.jpeg
  3. Vivado 2017.4.1

    Синтез схемы осуществился с одним предупреждением:

    »[Synth 8–5788] Register q_reg in module test is has both Set and reset with same priority. This may cause simulation mismatches. Consider rewriting code [»/home/vlasovdv0111/project_1/project_1.srcs/sources_1/new/test.v»:11]». Текст данной ошибки полностью повторяет текст ошибки для модуля test2.

    test4 Vivado
    f5x4xqfb1ycj6g_gbxakx_wrf8s.jpeg


Из всех описанных экспериментов можно сделать следующие выводы:

  1. язык Verilog является универсальным языком описания аппаратуры, ограничениями которого являются возможности самих сред разработки;
  2. для правильного описания аппаратуры необходимо знать синтаксис языка, а также анализировать списки предупреждений и ошибок, возникающих на каждом этапе построения проекта.

© Habrahabr.ru