How to generate synthesizable VHDL from Simulink block?

4 views (last 30 days)
hi, i have a descret PID controller and i want to generate a synthesizable VHDL code to implement on FPGA. i tried to generate a vhdl code which is shown below:
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.numeric_std.ALL;
ENTITY PID IS PORT(
clk : IN std_logic;
reset : IN std_logic;
clk_enable : IN std_logic );
END PID;
ARCHITECTURE rtl OF PID IS
-- Signals
SIGNAL enb : std_logic;
SIGNAL out1 : real := 0.0; -- double
SIGNAL Kd_T_out1 : real := 0.0; -- double
SIGNAL KiT_out1 : real := 0.0; -- double
SIGNAL Kp_out1 : real := 0.0; -- double
SIGNAL Step_out1 : real := 0.0; -- double
SIGNAL Discrete_output1 : real := 0.0; -- double
SIGNAL Memory9_out1 : real := 0.0; -- double
SIGNAL E_k : real := 0.0; -- double
SIGNAL Product7_out1 : real := 0.0; -- double
SIGNAL E_k_1 : real := 0.0; -- double
SIGNAL E_k_E_k_1 : real := 0.0; -- double
SIGNAL Product6_out1 : real := 0.0; -- double
SIGNAL Sum3_out1 : real := 0.0; -- double
SIGNAL E_k_2 : real := 0.0; -- double
SIGNAL Product8_out1 : real := 0.0; -- double
SIGNAL Sum2_out1 : real := 0.0; -- double
SIGNAL Sum8_out1 : real := 0.0; -- double
SIGNAL Product5_out1 : real := 0.0; -- double
SIGNAL Sum9_out1 : real := 0.0; -- double
BEGIN out1 <= 2.0000000000000000E+000;
Kd_T_out1 <= 1.0000000000000000E+001;
KiT_out1 <= 2.9999999999999999E-001;
Kp_out1 <= 1.0000000000000000E+000;
E_k <= Step_out1 - Discrete_output1;
Product7_out1 <= KiT_out1 * E_k;
Memory7_process : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
E_k_1 <= 0.0000000000000000E+000;
ELSIF clk'event AND clk = '1' THEN
IF enb = '1' THEN
E_k_1 <= E_k;
END IF;
END IF;
END PROCESS Memory7_process;
E_k_E_k_1 <= E_k - E_k_1;
Product6_out1 <= Kp_out1 * E_k_E_k_1;
Sum3_out1 <= Product7_out1 + Product6_out1;
Memory8_process : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
E_k_2 <= 0.0000000000000000E+000;
ELSIF clk'event AND clk = '1' THEN
IF enb = '1' THEN
E_k_2 <= E_k_1;
END IF;
END IF;
END PROCESS Memory8_process;
Product8_out1 <= E_k_1 * out1;
Sum2_out1 <= E_k_2 - Product8_out1;
Sum8_out1 <= Sum2_out1 + E_k;
Product5_out1 <= Sum8_out1 * Kd_T_out1;
Sum9_out1 <= Sum3_out1 + Product5_out1;
Discrete_output1 <= Memory9_out1 + Sum9_out1;
Memory9_process : PROCESS (clk, reset)
BEGIN
IF reset = '1' THEN
Memory9_out1 <= 0.0000000000000000E+000;
ELSIF clk'event AND clk = '1' THEN
IF enb = '1' THEN
Memory9_out1 <= Discrete_output1;
END IF;
END IF;
END PROCESS Memory9_process;
enb <= clk_enable;
END rtl;
the problem is that the generated code cant be compiled in the Quatus. and i see that the problem is in these data:
SIGNAL out1 : real := 0.0;
-- double SIGNAL Kd_T_out1 : real := 0.0;
-- double SIGNAL KiT_out1 : real := 0.0;
-- double SIGNAL Kp_out1 : real := 0.0;
-- double SIGNAL Step_out1 : real := 0.0;
-- double SIGNAL Discrete_output1 : real := 0.0;
-- double SIGNAL Memory9_out1 : real := 0.0;
-- double SIGNAL E_k : real := 0.0;
-- double SIGNAL Product7_out1 : real := 0.0;
-- double SIGNAL E_k_1 : real := 0.0;
-- double SIGNAL E_k_E_k_1 : real := 0.0;
-- double SIGNAL Product6_out1 : real := 0.0;
-- double SIGNAL Sum3_out1 : real := 0.0;
-- double SIGNAL E_k_2 : real := 0.0;
-- double SIGNAL Product8_out1 : real := 0.0;
-- double SIGNAL Sum2_out1 : real := 0.0;
-- double SIGNAL Sum8_out1 : real := 0.0;
-- double SIGNAL Product5_out1 : real := 0.0;
-- double SIGNAL Sum9_out1 : real := 0.0;
in which they must be std_logic and not real. so i didnt find which parameters can be set in matlab? thank you very much

Accepted Answer

Tim McBrayer
Tim McBrayer on 15 May 2013
If you do not want real numbers in your generated HDL code, you need to retype (in Simulink) all the doubles you have in your Simulink design. Any Simulink signal will be emitted as a real in VHDL or Verilog. Typically you will want to convert to fixed point data types; these will be emitted as std_logic_vector, signed, or unsigned, as is necessary. These types are all fully supported by Quartus.
You will need to understand the range your inputs can take, as well as the necessary precision, so that you can minimize the size of the vectors needed to implement your design.

More Answers (1)

Pham Van Dung
Pham Van Dung on 17 May 2013
Dear,
1. We can't implement double datatype in FPGA. Tim McBrayer is right. std_logic_vector, signed, or unsigned is support by Quartus
2. HDL library don't have PID discret, you have to make by your seft
3. If you convert from Simulink to HDL, still have an error and may be you have to solve the problem in Q- format number
  2 Comments
djalal ACHACHA
djalal ACHACHA on 19 May 2013
hi, i actually implemented the descret PID in simulink, and i can generate its VHDL code, but i dont want real, i want st_logic_vector. i ve changed all the doubles in my simulink desgin to fixdt, but still doesnt work.
Pham Van Dung
Pham Van Dung on 27 May 2013
Edited: Pham Van Dung on 27 May 2013
I can do it also but with 1ns in sample time of PID block, i can not implement it to get a good result.
You can use Datatype converter to convert the data to fixed-point data type before you implement in simulink block. Goodluck!

Sign in to comment.

Tags

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!