Каскадные условные присвоения переменной области

В R2021b HDL Coder™ предоставляет стандарт кодирования (Инструкция 2. F.B.1.a в Правилах Описания RTL и Проверках), чтобы проверять на присвоения на ту же переменную в нескольких каскадных областях управления в том же блоке процесса. HDL Coder указывает на блоки, которые генерируют такой стиль кодирования. Если стиль не рекомендуется для использования в вашем производственном рабочем процессе, рассмотрите альтернативный стиль кодирования или замените блок, на который указывает правило. Проверка отображает ошибку, если сгенерированный HDL-код для вашего проекта содержит ту же переменную для VHDL или укажите/соедините для Verilog записанный в в нескольких каскадных условных областях, таких как switch case или if/else каскадные области, в том же блоке процесса. Чтобы включить эту проверку на вашу модель, смотрите Проверку на присвоения на ту же переменную в нескольких каскадных областях управления.

Шаблоны в качестве примера, который Сбой Проверка на Инструкцию 2. F.B.1.a

Эти примеры показывают шаблоны HDL-кода, которые приводят проверку к сбою на присутствие присвоений на ту же переменную в нескольких каскадных условных областях.

Параллель, каскадная, 'если' области

always @(u) begin
    if(u < 8'sd4) begin
        y = -8'sd1;
    end
    if(u == 8'sd1) begin
        y = 8'sd10;
    else
        y =8'sd2;
    end
end

Параллель, каскадная, 'если' области с вложением

always @(u, k) begin​
    if (u < 8’sd4) begin​
        if(k == 8’sd1) begin ​
            y = 8'sd10;​
        end​
    end​    ​
    if (u < 8’sd2) begin​
        y = 8'sd1;​
    else​
        y = 8’sd2;​
    end​
end​

Параллель, каскадная, 'если' и области 'переключателя'

always @(u) begin​
    if (u < 8’sd4) begin​
        y = 8'sd10;​
    end​
    case (u)​
            8’sd1:​
                y = 8’sd11;​
            default:​
                y = 8’sd4;​
    endcase​
end​

Параллельные каскадные области 'переключателя'

always @(u) begin​
    case (u)​
            8’sd2:​
                y = 8’sd15;​
            default:​
                y = 8’sd4;​
    endcase​
    case (u)​
            8’sd1:​
                y = 8’sd11;​
            default:​
                y = 8’sd4;​
    endcase​
end​

Параллельная каскадная область во вложенной области

always @(u) begin​
    case (u)​
            8’sd2:​
                y = 8’sd15;​
            default:​
                 if (u < 8’sd4) begin​
                     y = 8'sd10;​
                 end​
    if (u == 8’sd1) begin​
                     y = 8'sd10;​
                 else​
                     y = 8’sd2;​
                 end​
    endcase​
end​

Шаблоны в качестве примера, который Передача Проверка на Инструкцию 2. F.B.1.a

Эти примеры показывают шаблоны HDL-кода, которые передают проверку на присутствие присвоений на ту же переменную в нескольких каскадных условных областях, если вы включаете проверку.

Значение по умолчанию и условное присвоение

always @(u) begin​
    y = 8’sd1;​
    if (u < 8’sd4) begin​
        y = 8'sd10;​
    end​
end​

Параллель, расположенная каскадом, “если” области, Пишущие в Различные Выходные параметры ​

always @(u) begin​
    if (u < 8’sd4) begin​
        y1 = -8'sd1;​
    else​
        y1 = 8’sd3;​
    end​   ​
    if (u == 8’sd1) begin​
        y2 = 8'sd10;​
    else​
        y2 = 8’sd2;​
    end​
end​

Присвоение во всех путях областей условия ​

always @(u) begin​
    if (u == 8’sd1) begin​
        y = 8'sd10;​
    else​
        y = 8’sd2;​
    end​
end​

Блоки Simulink и Шаблоны моделирования, который Сбой Проверка на Инструкцию 2. F.B.1.a

Некоторые блоки Simulink и шаблоны моделирования могут привести эту проверку к сбою (инструкция 2. F.B.1.a) и вызвать ошибку во время генерации HDL-кода. Если шаблон блока или моделирования, который вы используете в своем коде, приводит эту проверку к сбою, рассмотрите отключение проверки, если это не нужно в вашем производственном рабочем процессе или изменении блока или моделировании шаблона, производящего отказ кода.

Блок MATLAB Function

В некоторых случаях, MATLAB® код, записанный в блоках MATLAB Function, может сгенерировать HDL-код, который приводит эту проверку к сбою.

Условная Инициализация Персистентных Переменных.  Если персистентные переменные в блоке MATLAB Function условно инициализируются и затем перезаписываются в условной области в другом месте в коде, сгенерированный код может привести эту проверку к сбою.

Например, если у вас есть блок MATLAB Function в вашем DUT с кодом MATLAB:

function y = fcn(u)
 
persistent loc;
 
if(isempty(loc) || u == int8(2))
    loc = int8(-1);
end
 
% persistent variable overwritten in conditional code region
if(u<int8(4))
    loc = int8(10);
end
 
y = loc;

Этот фрагмент кода Verilog демонстрирует нарушение присвоения значения к переменной loc_temp в двух параллельных условных if операторы.

always @(loc, loc_not_empty, u) begin
    loc_temp = loc;
    loc_not_empty_next = loc_not_empty;
    if ( ! loc_not_empty || (u == 8'sd2)) begin
        loc_temp = -8'sd1;
        loc_not_empty_next = 1'b1;
    end
    // persistent variable overwritten in conditional code region
    if (u < 8'sd4) begin
        loc_temp = 8'sd10;
    end
    ...

end

Явное моделирование в блоке MATLAB Function.  Если вы устанавливаете Архитектуру HDL в диалоговом окне HDL Block Properties блока MATLAB Function как MATLAB Function и спроектируйте свой код MATLAB в стиле кодирования, который присваивает несколько значений той же переменной в каскадных условных областях, ошибка может произойти от получившихся шаблонов нарушения в сгенерированном HDL-коде.

Например, если у вас есть блок MATLAB Function в вашем DUT с кодом MATLAB:

function y = fcn(u)
 
% if region 1
if(u<4)
     
    % if region 1-1
    if(u==1)
        y = int8(0);
    else
        y = int8(4);
    end
     
    % if region 1-2
    if(u==2)
        y = int8(5);
    end
else
    y = int8(6);
end
 
...
 
end

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

module mlfb
            (u,
             y);

    ... 

    always @(u) begin
        // if region 1
        if (u < 8'sd4) begin
            // if region 1-1
            if (u == 8'sd1) begin
                y_1 = 8'sd0;
            end
            else begin
                y_1 = 8'sd4;
            end
            // if region 1-2
            if (u == 8'sd2) begin
                y_1 = 8'sd5;
            end
        end
        else begin
            y_1 = 8'sd6;
        end

        ...

    end
 
    assign y = y_1;
 
endmodule // mlfb

Условные Присвоения Матричных Переменных.  Если вы присваиваете различные индексы одной матрицы в нескольких каскадных условных областях в блоке MATLAB Function, нарушение может произойти.

Например, если у вас есть блок MATLAB Function в вашем DUT с кодом MATLAB:

function y = fcn(u)
 
y = int8(zeros(1,2));
 
% if region 1
if(u==1)
    y(1) = int8(2);
end
 
% if region 2
if(u==2)
    y(2) = int8(5);
end

Несмотря на то, что два различных индекса матричного y являются присвоенными значениями в расположении каскадом if операторы, этот код генерирует код Verilog, который вызывает нарушение.

ARCHITECTURE rtl OF mlfb IS
    -- Signals
    SIGNAL u_signed : signed(7 DOWNTO 0); -- int8
    SIGNAL y_tmp : vector_of_signed8(0 TO 1); -- int8 [2]
 
BEGIN
    u_signed <= signed(u);
 
    mlfb_1_output : PROCESS (u_signed)
    BEGIN
        FOR t_0 IN 0 TO 1 LOOP
            y_tmp(t_0) <= to_signed(16#00#, 8);
        END LOOP;
 
        -- if region 1
        IF u_signed = to_signed(16#00000001#, 8) THEN
            y_tmp(0) <= to_signed(16#02#, 8);
        END IF;
        -- if region 2
        IF u_signed = to_signed(16#00000002#, 8) THEN
            y_tmp(1) <= to_signed(16#05#, 8);
        END IF;
    END PROCESS mlfb_1_output;
 
    outputgen: FOR k IN 0 TO 1 GENERATE
        y(k) <= std_logic_vector(y_tmp(k));
    END GENERATE;
 
END rtl;

Обходные решения

  • Спроектируйте код MATLAB в своем блоке MATLAB Function способом, который избегает шаблонов, которые присваивают несколько значений той же переменной в нескольких каскадных условных областях.

  • Рассмотрите определение свойства HDL Block Архитектуры HDL блока MATLAB Function быть MATLAB Datapath.

Диаграммы Stateflow

В некоторых случаях, код MATLAB, написанный в Stateflow® chart может сгенерировать HDL-код, который нарушает эту проверку.

Явные шаблоны графика.  Каскадный if области, содержащие присвоения на ту же переменную в chart Stateflow, могут произвести эквивалентный шаблон в сгенерированном HDL-коде.

Cascaded if statements in a Stateflow Chart containing assignments to the same variable

Один if область в переходе, сопровождаемом другим if область в целевом состоянии может вызвать нарушение в сгенерированном HDL-коде. Этот шаблон замечен в этой диаграмме Stateflow:

if region in a transition followed by another if region in a destination state that both assigns values to the same variable in a Stateflow Chart.

С блоком MATLAB Function в переходе, содержащем код:

function y1 = fcn(u1)
    if(u1<4)
        y1 = int8(5);
    else
        y1 = int8(6);
    end
end

Обходное решение для обоих из этих явных нарушений шаблона графика должно изменить шаблон разработки, используемый в создании charts Stateflow. Избегайте использования явного if/else или switch/case области в вашем charts Stateflow. Вместо этого перепроектируйте необходимые потоки управления при помощи Stateflow семантика chart, такие как переходы и состояния.

Параллельное Разложение.  В Stateflow charts у вас есть опция, чтобы выбрать режим Parallel (AND) для свойства Decomposition графика, который изменяет выполнение графика, чтобы быть параллельным стилю. Для получения дополнительной информации смотрите Порядок выполнения для Параллельных состояний (Stateflow).

Например, когда вы задаете параллельное разложение в графике, оно приводит к генерации каскадного switch области в том же always процесс.

Stateflow chart with Parallel States and the chart property Decomposition set to Parallel (AND)

Если та же выходная переменная присвоена значение в нескольких параллельных состояниях, нарушение происходит в сгенерированном HDL-коде. Этот фрагмент кода Verilog демонстрирует нарушение присвоения значения к переменной y_1 в двух параллельных условных case операторы в том же always процесс, сгенерированный в результате параллельного разложения.

always @(is_A, is_B) begin
        is_A_next = is_A;
        is_B_next = is_B;
        case ( is_A)
            state_type_is_A_IN_A_1 :
            begin
                is_A_next = state_type_is_A_IN_A_2;
                y_1 = 8'sd2;
            end
            default :
            begin
                //case IN_A_2:
                y_1 = 8'sd2;
            end
        endcase
        case ( is_B)
            state_type_is_B_IN_B_1 :
            begin
                is_B_next = state_type_is_B_IN_B_2;
                y_1 = 8'sd4;
            end
            default :
            begin
                //case IN_B_2:
                y_1 = 8'sd4;
            end
        endcase
    end

Временная Логика.  Использование временной логики в вашем chart Stateflow обычно приводит к нарушениям. При некоторых условиях сгенерированный код не нарушает инструкцию по кодированию. Избегайте использования временной логики, чтобы гарантировать, что сгенерированный код не приводит к нарушению.

Основанный на LUT синус, блок косинуса

При использовании блока LUT-based Sine, Cosine в вашей модели, чтобы сгенерировать HDL-код, нарушение этой проверки может произойти в сгенерированном HDL-коде. Этот фрагмент кода Verilog, сгенерированный из модели Simulink, содержащей блок LUT-based Sine, Cosine, демонстрирует, что нарушение присвоения значения к переменной Look_Up_Table_k в нескольких параллельно условному if операторы.

always @(QuadHandle2_out1) begin
 
    Look_Up_Table_t_0_0[0] = 16'sb0000000000000000;
    ...
    Look_Up_Table_t_0_0[31] = 16'sb0011111111101100;
    Look_Up_Table_t_0_0[32] = 16'sb0100000000000000;
    Look_Up_Table_in0_0 = 18'sb000000000000000000;
    Look_Up_Table_in0_0_0 = 18'sb000000000000000000;
 
    if (QuadHandle2_out1 <= 18'sb000000000000000000) begin
        Look_Up_Table_k = 6'b000000;
    end
    else if (QuadHandle2_out1 >= 18'sb000100000000000000) begin
        Look_Up_Table_k = 6'b100000;
    end
    else begin
        Look_Up_Table_in0_0 = QuadHandle2_out1 >>> 8'd9;
        Look_Up_Table_k = Look_Up_Table_in0_0[5:0];
    end
     
    ...
     
    Look_Up_Table_dout_low = Look_Up_Table_t_0_0[Look_Up_Table_k];
    if ( ! (Look_Up_Table_k == 6'b100000)) begin
        Look_Up_Table_k = Look_Up_Table_k + 6'b000001;
    end
    ...
end

Для получения дополнительной информации смотрите Синус, Косинус.

Блок присвоения

Подобно нарушению, вызванному условными присвоениями матричных переменных в блоках MATLAB Function, блок Assignment может вызвать подобное нарушение в сгенерированном HDL-коде.

Например, модель, содержащая блок Assignment в DUT со свойством Index Option блока Assignment, имеющим больше чем одну размерность и набор к Index vector (port):

Assignment block in a model that causes a violation in the generated HDL Code

производит этот фрагмент кода Verilog:

always @* begin
    if ((In3 == 32'sb00000000000000000000000000000001) && (In3 == 32'sb00000000000000000000000000000001))
    begin
        assign_out1[0][0] = In2;
    end
    else begin
        assign_out1[0][0] = In1[0][0];
    end
    if ((In3 == 32'sb00000000000000000000000000000010) && (In3 == 32'sb00000000000000000000000000000001))
    begin
        assign_out1[1][0] = In2;
    end
    else begin
        assign_out1[1][0] = In1[1][0];
    end
 
    ...
 
    if ((In3 == 32'sb00000000000000000000000000000011) && (In3 == 32'sb00000000000000000000000000000011))
    begin
        assign_out1[2][2] = In2;
    end
    else begin
        assign_out1[2][2] = In1[2][2];
    end
end
Этот код Verilog нарушает проверку, потому что даже при том, что значения индекса, присвоенные матричной переменной assign_out1, отличаются между двумя, расположил каскадом if операторы, матричная переменная все еще присваивается несколько значений в каскадных условных областях.

Для получения дополнительной информации о блоке Assignment смотрите Присвоение.

Селекторный блок

Если блок Selector находится в модели, которая генерирует HDL-код, нарушение этой проверки может произойти.

Например, модель, содержащая блок Selector в DUT со свойством Index Option блока Selector, имеющим больше чем одну размерность и набор к Index vector (port):

Selector block in a Simulink Model

производит это сгенерировало код Verilog, который вызывает нарушение путем присвоения той же переменной Selector_out1, несколько значений для каждого из ее индексов в нескольких расположили каскадом if операторы.

always @* begin
    Selector_out1[0] = Bias_out1[0][3];
    Selector_out1[1] = Bias_out1[1][3];
    Selector_out1[2] = Bias_out1[2][3];
    Selector_out1[3] = Bias_out1[3][3];
    if (Sel == 32'b00000000000000000000000000000010) begin
        Selector_out1[0] = Bias_out1[0][2];
        Selector_out1[1] = Bias_out1[1][2];
        Selector_out1[2] = Bias_out1[2][2];
        Selector_out1[3] = Bias_out1[3][2];
    end
    if (Sel == 32'b00000000000000000000000000000001) begin
        Selector_out1[0] = Bias_out1[0][1];
        Selector_out1[1] = Bias_out1[1][1];
        Selector_out1[2] = Bias_out1[2][1];
        Selector_out1[3] = Bias_out1[3][1];
    end
    if (Sel == 32'b00000000000000000000000000000000) begin
        Selector_out1[0] = Bias_out1[0][0];
        Selector_out1[1] = Bias_out1[1][0];
        Selector_out1[2] = Bias_out1[2][0];
        Selector_out1[3] = Bias_out1[3][0];
    end
end

Для получения дополнительной информации о блоке Selector смотрите Селектор.

Набор блока математической функции как обратная величина

Если блок Math Function с набором Function как reciprocal, набор Algorithm method как Exact, и Saturate on integer overflow, выбранный как on находится в DUT в модели, которая генерирует HDL-код, нарушение этой проверки может произойти.

Например, модель, содержащая блок Math Function с предыдущими настройками

Reciprocal block inside the DUT of a model

производит этот Фрагмент кода Verilog, который демонстрирует нарушение присвоения значения к переменной ufix_sameasinput_out1 в двух параллельных условных if операторы:

always @(In1) begin
    ufix_sameasinput_div_temp = 16'b0000000000000000;
    if (In1 == 16'b0000000000000000) begin
        ufix_sameasinput_out1 = 16'b1111111111111111;
    end
    else begin
        ufix_sameasinput_div_temp = 13'b1000000000000 / In1;
        ufix_sameasinput_out1 = ufix_sameasinput_div_temp;
    end
    if (In1 == 16'b0000000000000000) begin
        ufix_sameasinput_out1 = 16'b1111111111111111;
    end
end

Для получения дополнительной информации о блоке Math Function смотрите Математическую функцию.

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте