В этом примере показано, как можно импортировать файл, содержащий код Verilog, и сгенерировать соответствующую модель Simulink при помощи importhdl
функция. importhdl
импорт и синтаксические анализы заданные файлы Verilog, чтобы сгенерировать соответствующую модель Simulink. Код Verilog в этом примере содержит алгоритм CORDIC atan2.
Этот файл входа Verilog реализует алгоритм CORDIC atan2.
cordic_atan2_verilog_file = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'cordic_atan2.v'); type(cordic_atan2_verilog_file);
`timescale 1ns / 1ps module cordic_atan2( input clk, // clock input reset, // reset to the system input enable, // enable input signed [15:0] x_in, // Input x value input signed [15:0] y_in, // Input Y value output reg signed [15:0] theta // Input theta value ); // Pipeline the input values reg signed [17:0]x_in_d; reg signed [17:0]y_in_d; always @(posedge clk) begin if(reset) begin x_in_d <={18{1'b0}}; y_in_d <={18{1'b0}}; end else if(enable) begin // extend the input values for intermediate calculations x_in_d <= {{2{x_in[15]}},x_in}; y_in_d <= {{2{y_in[15]}},y_in}; end end // pre quad correction logic reg x_qaud_adjust; reg y_qaud_adjust; reg y_non_zero; reg signed [17:0]x_pre_quad_out; reg signed [17:0]y_pre_quad_out; always @(posedge clk)begin if(reset)begin x_pre_quad_out <= {18{1'b0}}; y_pre_quad_out <= {18{1'b0}}; x_qaud_adjust <= 1'b0; y_qaud_adjust <= 1'b0; y_non_zero <=1'b0; end else if(enable)begin if(x_in_d[17] == 1'b1)begin x_pre_quad_out <= -x_in_d; x_qaud_adjust <= 1'b1; end else begin x_pre_quad_out <= x_in_d; x_qaud_adjust <= 1'b0; end if(y_in_d[17] == 1'b1)begin y_pre_quad_out <= -y_in_d; y_qaud_adjust <= 1'b1; y_non_zero <=1'b1; end else begin y_pre_quad_out <= y_in_d; y_qaud_adjust <= 1'b0; y_non_zero <= |y_in_d; // reduction or for test non zero or not end end end //LOOKUP TABLE FOR THE ANGLES wire signed [15:0]LUT[0:14]; wire signed [17:0]x_k[0:15]; wire signed [17:0]y_k[0:15]; wire signed [17:0]z_k[0:15]; wire signed [15:0]theta_temp; parameter PI = 16'sh6488; assign LUT[0] = 16'h1922; assign LUT[1] = 16'h0Ed6; assign LUT[2] = 16'h07D7; assign LUT[3] = 16'h03FB; assign LUT[4] = 16'h01FF; assign LUT[5] = 16'h0100; assign LUT[6] = 16'h0080; assign LUT[7] = 16'h0040; assign LUT[8] = 16'h0020; assign LUT[9] = 16'h0010; assign LUT[10] = 16'h0008; assign LUT[11] = 16'h0004; assign LUT[12] = 16'h0002; assign LUT[13] = 16'h0001; assign LUT[14] = 16'h0000; assign x_k[0] = x_pre_quad_out; assign y_k[0] = y_pre_quad_out; wire signed [17:0]theta_temp0; assign theta_temp0 = z_k[15]; assign theta_temp = theta_temp0[15:0]; assign z_k[0] = 18'd0; //cordic iterator genvar i; generate for (i = 0; i<15; i =i+1) begin Kernel cordic_iterator (.clk (clk), .reset(reset), .enable (enable ), .itr_num(i), .x_in(x_k[i]), .y_in(y_k[i]), .z_in(z_k[i]), .lut_constant(LUT[i]), .x_out(x_k[i+1]), .y_out(y_k[i+1]), .z_out(z_k[i+1]) ); end endgenerate // matching delays for the control signls of the pre quadrant correction logic reg x_qaud_adjust_match_delay[0:14]; reg y_qaud_adjust_match_delay[0:14]; reg y_non_zero_match_delay[0:14]; integer k; always @(posedge clk)begin if(reset)begin x_qaud_adjust_match_delay[0] <= 1'b0; y_qaud_adjust_match_delay[0] <= 1'b0; y_non_zero_match_delay [0] <= 1'b0; x_qaud_adjust_match_delay[1] <= 1'b0; y_qaud_adjust_match_delay[1] <= 1'b0; y_non_zero_match_delay [1] <= 1'b0; x_qaud_adjust_match_delay[2] <= 1'b0; y_qaud_adjust_match_delay[2] <= 1'b0; y_non_zero_match_delay [2] <= 1'b0; x_qaud_adjust_match_delay[3] <= 1'b0; y_qaud_adjust_match_delay[3] <= 1'b0; y_non_zero_match_delay [3] <= 1'b0; x_qaud_adjust_match_delay[4] <= 1'b0; y_qaud_adjust_match_delay[4] <= 1'b0; y_non_zero_match_delay [4] <= 1'b0; x_qaud_adjust_match_delay[5] <= 1'b0; y_qaud_adjust_match_delay[5] <= 1'b0; y_non_zero_match_delay [5] <= 1'b0; x_qaud_adjust_match_delay[6] <= 1'b0; y_qaud_adjust_match_delay[6] <= 1'b0; y_non_zero_match_delay [6] <= 1'b0; x_qaud_adjust_match_delay[7] <= 1'b0; y_qaud_adjust_match_delay[7] <= 1'b0; y_non_zero_match_delay [7] <= 1'b0; x_qaud_adjust_match_delay[8] <= 1'b0; y_qaud_adjust_match_delay[8] <= 1'b0; y_non_zero_match_delay [8] <= 1'b0; x_qaud_adjust_match_delay[9] <= 1'b0; y_qaud_adjust_match_delay[9] <= 1'b0; y_non_zero_match_delay [9] <= 1'b0; x_qaud_adjust_match_delay[10] <= 1'b0; y_qaud_adjust_match_delay[10] <= 1'b0; y_non_zero_match_delay [10] <= 1'b0; x_qaud_adjust_match_delay[11] <= 1'b0; y_qaud_adjust_match_delay[11] <= 1'b0; y_non_zero_match_delay [11] <= 1'b0; x_qaud_adjust_match_delay[12] <= 1'b0; y_qaud_adjust_match_delay[12] <= 1'b0; y_non_zero_match_delay [12] <= 1'b0; x_qaud_adjust_match_delay[13] <= 1'b0; y_qaud_adjust_match_delay[13] <= 1'b0; y_non_zero_match_delay [13] <= 1'b0; x_qaud_adjust_match_delay[14] <= 1'b0; y_qaud_adjust_match_delay[14] <= 1'b0; y_non_zero_match_delay [14] <= 1'b0; end else if(enable) begin x_qaud_adjust_match_delay[0] <=x_qaud_adjust; y_qaud_adjust_match_delay[0] <=y_qaud_adjust; y_non_zero_match_delay[0] <=y_non_zero; for(k =0; k <14 ;k = k+1)begin x_qaud_adjust_match_delay[k+1] <= x_qaud_adjust_match_delay[k]; y_qaud_adjust_match_delay[k+1] <= y_qaud_adjust_match_delay[k]; y_non_zero_match_delay[k+1] <= y_non_zero_match_delay[k]; end end end // post quadrant correction logic always @(posedge clk) begin if(reset) theta<=16'd0; else if(enable)begin if(y_non_zero_match_delay[14])begin if(x_qaud_adjust_match_delay[14])begin if(y_qaud_adjust_match_delay[14]) theta <=theta_temp -PI; else theta <=PI -theta_temp; end else begin if(y_qaud_adjust_match_delay[14]) theta <= -theta_temp; else theta <= theta_temp; end end else if(x_qaud_adjust_match_delay[14])begin theta <= PI; end else begin theta <= 16'd0; end end end endmodule module Kernel( input clk, input reset, input enable, input signed [17:0]x_in, input signed [17:0]y_in, input signed [17:0]z_in, input [4:0]itr_num, input signed [15:0]lut_constant, output reg signed [17:0]x_out, output reg signed [17:0]y_out, output reg signed [17:0]z_out); wire signed [17:0] lut_constant_signExtension = {{2{lut_constant[15]}},lut_constant}; always @(posedge clk)begin if(reset)begin x_out <={18{1'b0}}; y_out <={18{1'b0}}; z_out <= {18{1'b0}}; end else if(enable)begin if(y_in[17])begin x_out <= x_in -(y_in>>>itr_num); y_out <= y_in + (x_in>>>itr_num); z_out <= z_in - lut_constant_signExtension; end else begin x_out <= x_in +(y_in>>>itr_num); y_out <= y_in - (x_in>>>itr_num); z_out <= z_in + lut_constant_signExtension; end end end endmodule
Этот проект Verilog содержит различные обычно используемые построения Verilog, такие как:
Непрерывные присвоения
Всегда блоки
Условные операторы
Инстанцирование модуля
Сгенерируйте построения
Цикл for
Чтобы импортировать файл Verilog, задайте имя файла в качестве аргумента к importhdl
функция.
importhdl(cordic_atan2_verilog_file);
### Parsing <a href="matlab:edit('/mathworks/devel/bat/BR2021ad/build/matlab/toolbox/hdlcoder/hdlcoderdemos/cordic_atan2.v')">cordic_atan2.v</a>. ### Top Module name: 'cordic_atan2'. ### Identified ClkName::clk. ### Identified RstName::reset. ### Identified ClkEnbName::enable. Warning: Unused signals detected in the Demux block created for vector index signal 'x_k'. A Demux block created for a vector index signal has all possible output signals based on the size and dimensions provided. Warning: Unused signals detected in the Demux block created for vector index signal 'y_k'. A Demux block created for a vector index signal has all possible output signals based on the size and dimensions provided. ### Hdl Import parsing done. ### Removing unconnected components. ### Unconnected components detected when importing the HDL code. These components are removed from the generated Simulink model. ### Begin model generation. ### Creating Target model cordic_atan2 ### Start Layout... ### Working on hierarchy at ---> 'cordic_atan2'. ### Laying out components. ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2'. ### Laying out components. ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator1'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator10'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator11'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator12'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator13'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator14'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator2'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator3'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator4'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator5'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator6'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator7'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator8'. ### Laying out components. ### Drawing block edges... ### Working on hierarchy at ---> 'cordic_atan2/cordic_atan2/cordic_iterator9'. ### Laying out components. ### Drawing block edges... ### Drawing block edges... ### Drawing block edges... ### Model generation complete. ### Setting model parameters. ### Generated model file /tmp/BR2021ad_1584584_202060/publish_examples2/tp4385e7eb/hdlimport/cordic_atan2/cordic_atan2.slx. ### Importhdl completed.
importhdl
анализирует входной файл и отображает сообщения процесса импорта в Командном окне MATLAB™. Импорт обеспечивает ссылку на сгенерированную модель Simulink cordic_atan2.slx
. Сгенерированная модель использует то же имя в качестве главного модуля в файле входа Verilog.
Чтобы открыть сгенерированную модель Simulink, щелкните по ссылке в Командном окне. Модель сохранена в hdlimport/cordic_atan2
путь относительно текущей папки. Можно симулировать модель и наблюдать результаты симуляции.
open_system('hdlimport/cordic_atan2/cordic_atan2') Simulink.BlockDiagram.arrangeSystem('cordic_atan2') set_param('cordic_atan2', 'UnconnectedOutputMsg', 'None'); sim('hdlimport/cordic_atan2/cordic_atan2.slx');
Код Verilog инстанцирует 15
модули ядра при помощи сгенерировать построения. В сгенерированной модели Simulink, 15
модули ядра замечены.
generate for (i = 0; i<15; i =i+1) begin Kernel cordic_iterator (.clk(clk), .reset(reset), .enable(enable), .itr_num(i), .x_in(x_k[i]), .y_in(y_k[i]), .z_in(z_k[i]), .lut_constant(LUT[i]), .x_out(x_k[i+1]), .y_out(y_k[i+1]), .z_out(z_k[i+1])); end endgenerate
module Kernel( input clk, input reset, input enable, input signed [17:0]x_in, input signed [17:0]y_in, input signed [17:0]z_in, input [4:0]itr_num, input signed [15:0]lut_constant, output reg signed [17:0]x_out, output reg signed [17:0]y_out, output reg signed [17:0]z_out);
wire signed [17:0] lut_constant_signExtension = {{2{lut_constant[15]}},lut_constant};
always @(posedge clk)begin if(reset)begin x_out <={18{1'b0}}; y_out <={18{1'b0}}; z_out <= {18{1'b0}}; end else if(enable)begin if(y_in[17])begin x_out <= x_in -(y_in>>>itr_num); y_out <= y_in + (x_in>>>itr_num); z_out <= z_in - lut_constant_signExtension; end else begin x_out <= x_in +(y_in>>>itr_num); y_out <= y_in - (x_in>>>itr_num); z_out <= z_in + lut_constant_signExtension; end end end
endmodule