В R2021b HDL Coder™ предоставляет стандарт кодирования (Инструкция 2. F.B.1.a в Правилах Описания RTL и Проверках), чтобы проверять на присвоения на ту же переменную в нескольких каскадных областях управления в том же блоке процесса. HDL Coder указывает на блоки, которые генерируют такой стиль кодирования. Если стиль не рекомендуется для использования в вашем производственном рабочем процессе, рассмотрите альтернативный стиль кодирования или замените блок, на который указывает правило. Проверка отображает ошибку, если сгенерированный HDL-код для вашего проекта содержит ту же переменную для VHDL
или укажите/соедините для Verilog
записанный в в нескольких каскадных условных областях, таких как switch case
или if/else
каскадные области, в том же блоке процесса. Чтобы включить эту проверку на вашу модель, смотрите Проверку на присвоения на ту же переменную в нескольких каскадных областях управления.
Эти примеры показывают шаблоны 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
Эти примеры показывают шаблоны 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) и вызвать ошибку во время генерации HDL-кода. Если шаблон блока или моделирования, который вы используете в своем коде, приводит эту проверку к сбою, рассмотрите отключение проверки, если это не нужно в вашем производственном рабочем процессе или изменении блока или моделировании шаблона, производящего отказ кода.
В некоторых случаях, 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
.
В некоторых случаях, код MATLAB, написанный в Stateflow® chart может сгенерировать HDL-код, который нарушает эту проверку.
Явные шаблоны графика. Каскадный if
области, содержащие присвоения на ту же переменную в chart Stateflow, могут произвести эквивалентный шаблон в сгенерированном HDL-коде.
Один if
область в переходе, сопровождаемом другим if
область в целевом состоянии может вызвать нарушение в сгенерированном HDL-коде. Этот шаблон замечен в этой диаграмме Stateflow:
С блоком 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
процесс.
Если та же выходная переменная присвоена значение в нескольких параллельных состояниях, нарушение происходит в сгенерированном 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-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)
:
производит этот фрагмент кода 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
if
операторы, матричная переменная все еще присваивается несколько значений в каскадных условных областях. Для получения дополнительной информации о блоке Assignment смотрите Присвоение.
Если блок Selector находится в модели, которая генерирует HDL-код, нарушение этой проверки может произойти.
Например, модель, содержащая блок Selector в DUT со свойством Index Option блока Selector, имеющим больше чем одну размерность и набор к Index vector (port)
:
производит это сгенерировало код 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 с предыдущими настройками
производит этот Фрагмент кода 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 смотрите Математическую функцию.