News:

Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

PI Control in foc.cpp

Started by shivang1993, June 24, 2019, 10:08:11 PM

Previous topic - Next topic

shivang1993

I have a couple of questions regarding the code given in foc.cpp:

1.  Are the int variables defined 16-bit or 32-bit? If they are 32-bit, then why the value of MAX_LIM and MIN_LIM (defined in foc.h) are 32767 and -32767, respectively, while using Clip32 function? Shouldn't it be 2^31 if the signed integer bit is 32 bit. The same happens for the integral error max and min value. While they are being stored as 48 bit signed integer, the maximum error value they can have is only 16777215 (line 40 in foc.cpp).

2. Whenever the PI control function is called, the set point is passed as negative of the actual value set. For eg. the speed PI control function is called as:
RPM_Out = PI_Control(RPM_filtered, -args[RPM_SP_REG], args[RPM_KP_REG], args[RPM_KI_REG], Mode_Change, RPM_GiE_prev). As we can see the set point is passed as the negative of args[RPM_SP_REG]. Why is that? Looking at the definition of the function as defined in lines 100-120, it should be passed as it is.

3. RPM_filtered, Id, Iq are also passed to status registers with negation. Why?

4. In the foc.h file, are the Kp, Ki values being stored in 16-bit registers or 32-bit?

5. Is there an example foc code available  with floating point operation instead of fixed-point arithmetic?

Andrei Errapart

Quote from: shivang1993 on June 24, 2019, 10:08:11 PM
1.  Are the int variables defined 16-bit or 32-bit? If they are 32-bit, then why the value of MAX_LIM and MIN_LIM (defined in foc.h) are 32767 and -32767, respectively, while using Clip32 function? Shouldn't it be 2^31 if the signed integer bit is 32 bit. The same happens for the integral error max and min value. While they are being stored as 48 bit signed integer, the maximum error value they can have is only 16777215 (line 40 in foc.cpp).
The variables of type integer are 32-bit, because the fictional target for the C compiler in the HLS is a 32-bit microprocessor. 16-bit integers are usually used when the target microprocessor is 16-bit or 8-bit.

The definitions MAX_LIM and MIN_LIM are not for the numerical limits of the chosen variable type, but for the saturated 16-bit arithmetic. The intermediate results can occupy up to 32 bits in the case of multiplication. Not reserving enough bits for the intermediate results in undetected integer operation overflow and incorrect values.

The use of 32-bit variables was chosen out of convenience, because it matches the default size of integers and also the AXI bus transaction size.

You can optimize the storage space by using optimal bit width for the variables, but while optimizing you have to make sure that enough bits are used for the intermediate results.

Quote from: shivang1993 on June 24, 2019, 10:08:11 PM
2. Whenever the PI control function is called, the set point is passed as negative of the actual value set. For eg. the speed PI control function is called as:
RPM_Out = PI_Control(RPM_filtered, -args[RPM_SP_REG], args[RPM_KP_REG], args[RPM_KI_REG], Mode_Change, RPM_GiE_prev). As we can see the set point is passed as the negative of args[RPM_SP_REG]. Why is that? Looking at the definition of the function as defined in lines 100-120, it should be passed as it is.

3. RPM_filtered, Id, Iq are also passed to status registers with negation. Why?
I don't recall the exact circumstances, but at one point in the development it was necessary to invert the rotation direction. I think this is why there are the negations.


Quote from: shivang1993 on June 24, 2019, 10:08:11 PM
4. In the foc.h file, are the Kp, Ki values being stored in 16-bit registers or 32-bit?
All the registers contain 32-bit. The Kp, Ki have been specified to have fixed point format of Q16.16, e.g. 16 integer bits and 16 fractional bits.

Quote from: shivang1993 on June 24, 2019, 10:08:11 PM
5. Is there an example foc code available with floating point operation instead of fixed-point arithmetic?
No.

Let me note that the floating point operations are relatively expensive to implement in comparision to the equivalent fixed point arithmetic. See the documentation for the DSP slices DSP48E2 to see what integer arithmetic operations are directly supported by the hardware on the FPGA.

shivang1993

Thank you so much Andrei for the quick response. I am using a different motor with the board and I have a few more queries about the evaluation board:

1. Do I have to build the project from scratch every time I make some changes to foc.h file? It takes about 30 minutes for the complete build process. Is there any shortcut to build only the incremental change?

2. Do I need to change the value of CPR in focserver.h file if I am using a different encoder? I changed the value in foc.h and sin_cos_table.h but don't know if "ppr" variable in focserver.h also needs to be changed.

3. Also if I want to change something in focserver.conf file (like the Kp and Ki values), do I need to build the project as usual or are there any extra steps involved as well?

4. Is there a possibility to get the PCB sheet with the complete layout of the EDPS board? In the EDPS user manual, the basic block diagram is given but not the complete layout of the board.

shivang1993

I also have a couple of other queries :

1. The outputs of foc.cpp is the pwm pulse made by the three phase voltages: pwm = MAKE_DATA4(Van, Vbn, Vcn, 0). This means all the phase voltages are only occupying 16 bits each. Going by the resolution of pwm (=0.0003662), this means a maximum of 12 V on each phase voltage. While this enough for the motor that came with the kit, this is not enough for an external motor which I am trying to power using a 48 V DC supply. So my question is whether the resolution of pwm gets modified automatically (according to the magnitude of dc bus) or do we have to externally change it so as to accommodate higher voltages than 12 V? If so, how do we change the pwm resolution?

2. Also how can we observe pwm frequency and change it as needed? I could not find any necessary file for doing this in the folder obtained from Github. Will we need Xilinx Vivado for doing that? So far I have been just using Xilinx SDSoC for the control.

Thanks

Andrei Errapart

Quote from: shivang1993 on July 08, 2019, 10:33:54 PM
1. Do I have to build the project from scratch every time I make some changes to foc.h file? It takes about 30 minutes for the complete build process. Is there any shortcut to build only the incremental change?
Yes. There is no way around it.

Quote from: shivang1993 on July 08, 2019, 10:33:54 PM
2. Do I need to change the value of CPR in focserver.h file if I am using a different encoder? I changed the value in foc.h and sin_cos_table.h but don't know if "ppr" variable in focserver.h also needs to be changed.
CPR has to match the number of pulses per revolution of the encoder.
PPR has to match the number of poles of the motor.

Quote from: shivang1993 on July 08, 2019, 10:33:54 PM
3. Also if I want to change something in focserver.conf file (like the Kp and Ki values), do I need to build the project as usual or are there any extra steps involved as well?
Not really.

For temporary changes you can just edit the file in the running system and restart focserver by executing the following command on the console /etc/init.d/focinit restart

For permanent changes, see the file "init.sh" on the SD card. There are commands to copy the file "focserver.conf", but they are commented out. Uncomment them. You can find the "init.sh" script in the repository at "focserver/files/sd_card/init.sh". Place your copy of the "focserver.conf" to the SD card and restart the board.

Quote from: shivang1993 on July 08, 2019, 10:33:54 PM
4. Is there a possibility to get the PCB sheet with the complete layout of the EDPS board? In the EDPS user manual, the basic block diagram is given but not the complete layout of the board.
Please take the trouble to send e-mail with that request to support@trenz-electronic.de . You might be asked additional questions.

Andrei Errapart

Quote from: shivang1993 on July 09, 2019, 10:35:36 PM
1. The outputs of foc.cpp is the pwm pulse made by the three phase voltages: pwm = MAKE_DATA4(Van, Vbn, Vcn, 0). This means all the phase voltages are only occupying 16 bits each. Going by the resolution of pwm (=0.0003662), this means a maximum of 12 V on each phase voltage. While this enough for the motor that came with the kit, this is not enough for an external motor which I am trying to power using a 48 V DC supply. So my question is whether the resolution of pwm gets modified automatically (according to the magnitude of dc bus) or do we have to externally change it so as to accommodate higher voltages than 12 V? If so, how do we change the pwm resolution?
The conversion constant is valid only when the power supply voltage is 12V as well. The focserver doesn't automatically take into account that you have supplied 48V instead of 12V.

The conversion factor "pwm2V" is used in the UI only.

Quote from: shivang1993 on July 09, 2019, 10:35:36 PM
2. Also how can we observe pwm frequency and change it as needed? I could not find any necessary file for doing this in the folder obtained from Github. Will we need Xilinx Vivado for doing that? So far I have been just using Xilinx SDSoC for the control.
The PWM frequency is a design-time paramater of the PWM IP core block.

To change it, start the Vivado that came with Vivado SDSoC by starting "Xilinx\SDx\2017.1\Vivado\bin\vivado.bat" and open the corresponding platform design, for example, "IIoT-EDDP\SDSoC\platforms\arty_z7_10_foc\hw\vivado\arty_z7_10_foc.xpr"

By the way, when you change the PWM frequency, the actual resolution of the PWM changes; the IP core automatically scales the 16-bit input parameters to match the actual resolution of the PWM.

shivang1993

Hey Andrei,

1. How can I save the output of a status register (for example Angle) in a file on my local pc while the motor is running?

2. I am trying to change the motor speed set point continuously by changing the register RPMSp in the serial console. Is there a way to automate this so that I do not have to keep changing it manually?

3. A couple of hardware blocks have been implemented as an IP core like the PWM core (zsys_axis_pwm_0_0). Can we modify the implementation in this IP Core? If so, what is the procedure?

4. This motor control was implemented using SDSoC but it looks like everything can be implemented using Vivado HLS as well by integrating all the IP cores given in "IIoT-EDDP\HLS\ARTY_Z7_FULL". While I could find all the IP Cores individually, I could not locate the .xpr file which included all the IP cores together just like with SDSoC. So do you provide that particular file or do we have to integrate all the separate IP Cores in order to use Vivado to create the bitstream file. This would help us in avoiding the use of Xilinx SDSoC.

Thanks
Shivang

Andrei Errapart

Quote from: shivang1993 on July 22, 2019, 10:39:28 PM
1. How can I save the output of a status register (for example Angle) in a file on my local pc while the motor is running?
The software provided doesn't support writing any files to your PC.

One option is to add Vivado ILA and capture a stream of data and save it to your PC. The amount of data captured is limited by the BRAM on the FPGA device.

Another option is to do some programming work. Both the Web Application and the focserver can be modified to suit your needs.


Quote from: shivang1993 on July 22, 2019, 10:39:28 PM
2. I am trying to change the motor speed set point continuously by changing the register RPMSp in the serial console. Is there a way to automate this so that I do not have to keep changing it manually?
Continuous sweep is not supported by the existing software. You can write a program to continuously update the registers you need, either directly or indirectly through "focserver" and the websockets.

Quote from: shivang1993 on July 22, 2019, 10:39:28 PM
3. A couple of hardware blocks have been implemented as an IP core like the PWM core (zsys_axis_pwm_0_0). Can we modify the implementation in this IP Core? If so, what is the procedure?
See the UG1119 "Creating, Packaging Custom IP Tutorial" by Xilinx. In the case of the SDSoC design, see also the the Point 2 in my last answer.

Quote from: shivang1993 on July 22, 2019, 10:39:28 PM
4. This motor control was implemented using SDSoC but it looks like everything can be implemented using Vivado HLS as well by integrating all the IP cores given in "IIoT-EDDP\HLS\ARTY_Z7_FULL". While I could find all the IP Cores individually, I could not locate the .xpr file which included all the IP cores together just like with SDSoC. So do you provide that particular file or do we have to integrate all the separate IP Cores in order to use Vivado to create the bitstream file. This would help us in avoiding the use of Xilinx SDSoC.
See https://wiki.trenz-electronic.de/display/PD/Project+Delivery for the help on the scripts provided for creating and developing the Vivado Project.
Quickstart is as follows:
1. Run _create_win_setup.cmd
2. Optional: Edit design_basic_settings.cmd; this is needed when your Xilinx install is in a non-default location
3. Run vivado_open_existing_project_guimode.cmd

There are small differences between the HLS project and the SDSoC project which might get you, but by and large they behave the same.

The IP cores have been created separately. See the directory "design_hls" and the UG902 "High-Level Synthesis" by Xilinx.

shivang1993

Hey Andrei,

It looks to me SDSoC being so new to the Xilinx family still doesn't support a lot of features. So I was trying to run the Vivado project by using https://wiki.trenz-electronic.de/display/PD/Project+Delivery. At first I had to uninstall Vivado which was installed with SDSoC since the paths defined in design_basic_settings.cmd were meant for Standalone Vivado. After installing Xilinx Vivado Webpack 2017.1 and setting the appropriate board number, I ran the vivado_open_existing_project_guimode.cmd but the got following error:

#-----------------------------------------------------------
# Vivado v2017.1 (64-bit)
# SW Build 1846317 on Fri Apr 14 18:55:03 MDT 2017
# IP Build 1846188 on Fri Apr 14 20:52:08 MDT 2017
# Start of session at: Wed Jul 24 16:38:55 2019
# Process ID: 9488
# Current directory: C:/Users/USSHAGR1/Downloads/IIoT-EDDP-master/IIoT-EDDP-master/HLS/ARTY_Z7_FULL/console/base_cmd/v_log
# Command line: vivado.exe -source ../scripts/script_main.tcl -mode batch -notrace -tclargs --gui 1
# Log file: C:/Users/USSHAGR1/Downloads/IIoT-EDDP-master/IIoT-EDDP-master/HLS/ARTY_Z7_FULL/console/base_cmd/v_log/vivado.log
# Journal file: C:/Users/USSHAGR1/Downloads/IIoT-EDDP-master/IIoT-EDDP-master/HLS/ARTY_Z7_FULL/console/base_cmd/v_log\vivado.jou
#-----------------------------------------------------------
source ../scripts/script_main.tcl -notrace
couldn't read file "../scripts/script_main.tcl": no such file or directory
INFO: [Common 17-206] Exiting Vivado at Wed Jul 24 16:39:01 2019...

Can you help me in resolving this error?

Thanks a lot

JH

Hi,

there is a readme in the base folder
Quote

1. Create Command Files and open documentation links:
  On Windows OS: run "_create_win_setup.cmd" and follow setup instructions

and also a readme in the ./console/ folder:
QuoteConsole command files for reference design root directory.
from the part of your log file, I would say you run it
Use console command file for generation:
_create_linux_setup.sh
_create_win_setup.cmd

For the part of your log file, I see that you start cmd  in /console/base_cmd/ thats wrong!


An:
Quote
At first I had to uninstall Vivado which was installed with SDSoC since the paths defined in design_basic_settings.cmd were meant for Standalone Vivado.
I think on this SDSoC version uninstall was not necessary, only install normal Vivado version.

br
John



Andrei Errapart

Quote from: shivang1993 on July 24, 2019, 10:56:57 PM
... I ran the vivado_open_existing_project_guimode.cmd but the got following error: ...
When it is the first time, run "vivado_create_project_guimode.cmd". It will work: it will create Vivado project and open it.

My fault for not mentioning it.

shivang1993

Thanks John and Andrei. I was opening the vivado_create_project_guimode.cmd from inside the console folder. Thats why I was getting that error. I was able to run the command successfully, create the ARTY_Z7_FULL.xpr and generate the bitstream without any problems. However, when I tried to program the device using the Hardware manager, I got the following error:

ERROR: [Labtools 27-3303] Incorrect bitstream assigned to device. Bitfile is incompatible for this device.

I tried to use the TCL command "set_param xicom.use_bitstream_version_check false" to get rid of this error but the same error kept coming up. Same happened with using SDK. I am using the Arty Z7 -10 board and I updated the board in the project settings accordingly. Is there a way to get around this error?

Thanks

JH

which arty board did you use? And what did you select for project creation?
You must select the correct one before you create the project. ARTY-Z7-10  or ARTY-Z7-20 is possible.
br
John

shivang1993

I am using Arty Z7 10 board and have set the board accordingly in the project manager. But I keep getting the same error (ERROR: [Labtools 27-3303] Incorrect bitstream assigned to device. Bitfile is incompatible for this device.).

I have attached the pictures of both the Project Manager and Hardware Manager taken from Vivado Webpack 2017.1.

Andrei Errapart

Although I have never used this project in this manner, but I would expect direct loading of bitfile to work. I have re-generated boot.bin always, because it is very little extra trouble and in the end one has to re-generate it anyway in order to make changes persistent.

Try executing the TCL command "TE::hw_build_design -export_prebuilt". This will generate new boot file "prebuilt\boot_images\arty_z7_10_edps\u-boot\BOOT.bin". Replace the "boot.bin" on the SD card with the newly generated one and reboot the ARTY-Z7.

shivang1993

Actually I am trying to generate the .bit file and load it directly over the JTAG port. So I am not using SD card like I used while using SDSoC. Is there a way to generate .elf file with Xilinx Vivado which can be used with SD Card?

The whole reason of moving to Xilinx Vivado from SDSoC was the freedom to use Xilinx ILA core for real-time debugging. But I am struggling to put the .bit file to the Arty Z7 board. I noticed that the board files that came with IIoT EDDP Master were different from the ones provided by Digilent (https://reference.digilentinc.com/reference/software/vivado/board-files?redirect=1). I tried to use the board files given by Digilent but the build command (vivado_create_project_guimode.cmd) did not go through. I also tried to use the board files provided by Trenz for an example by Digilent (https://reference.digilentinc.com/learn/programmable-logic/tutorials/arty-z7-getting-started-with-zynq/start) and failed there. Considering these board files are different, this may be one of the reasons for this failure.

Also with using SDSoC, I could change Kp Ki values using the focserver. How can this be done using with the HLS design? The Kp, Ki's values seem to be stored in registers. So is it even possible to change them while the motor is running? Is it possible to use focserver and web gui with the HLS design as well?

Andrei Errapart

Quote from: shivang1993 on July 30, 2019, 05:13:13 AM
Actually I am trying to generate the .bit file and load it directly over the JTAG port. So I am not using SD card like I used while using SDSoC. Is there a way to generate .elf file with Xilinx Vivado which can be used with SD Card?
Perhaps you are confusing SDSoC with ordinary Vivado. They operate differently. Ordinary Vivado doesn't output .elf files except with the help of Xilinx SDK as an external tool.

Let me note that in addition to the .bit file, which contains PL (programmable logic) configuration, it also needs a program on the PS (programming system) to control the FOC over the AXI bus by writing and monitoring FOC registers. The program "focserver" runs on a Linux operating system. See page 20 in the file "EDDP User Manual.pdf" for the block diagram. If you don't need the network services provided by Linux, one can get away with a bare metal programing controlling the EDPS board.

The file "boot.bin" is constructed from the following files:
1. FSBL.elf, which configures the PL part of the Zynq with the .bit file and starts the u-boot.elf
2. system.bit, which contains configuration for the PL.
3. u-boot.elf, which decompresses Linux image file "image.ub" into the memory and starts the Linux kernel.
In the case of the SDSoC, there are additional files on the boot device (SD card).

Quote from: shivang1993 on July 30, 2019, 05:13:13 AM
The whole reason of moving to Xilinx Vivado from SDSoC was the freedom to use Xilinx ILA core for real-time debugging. But I am struggling to put the .bit file to the Arty Z7 board. I noticed that the board files that came with IIoT EDDP Master were different from the ones provided by Digilent (https://reference.digilentinc.com/reference/software/vivado/board-files?redirect=1). I tried to use the board files given by Digilent but the build command (vivado_create_project_guimode.cmd) did not go through. I also tried to use the board files provided by Trenz for an example by Digilent (https://reference.digilentinc.com/learn/programmable-logic/tutorials/arty-z7-getting-started-with-zynq/start) and failed there. Considering these board files are different, this may be one of the reasons for this failure.
To put the .bit file to the Arty Z7 board, I recommend generating the boot.bin (this includes .bit file) with the TCL command "TE::hw_build_design -export_prebuilt" and copy it over to the SD card and boot the Arty from the SD card.

Let me recommend starting with the reference design and do the modifications step by step, verifying the result at each step. Why you want to use board files other than what was included in the reference design?

In order to use ILA on the SDSoC project, it has to be in the platform design and one has to modify the foc.cpp to provide debug data. It takes more planning and is more work.

You can also do software simulation, by including the function foc() in an ordinary C++ program and providing suitable inputs and checking outputs.

Quote from: shivang1993 on July 30, 2019, 05:13:13 AM
Also with using SDSoC, I could change Kp Ki values using the focserver. How can this be done using with the HLS design? The Kp, Ki's values seem to be stored in registers. So is it even possible to change them while the motor is running? Is it possible to use focserver and web gui with the HLS design as well?
Yes, it is possible to change them even while the motor is running. The focserver has a command line option "-w REG=VAL" exactly for that purpose, see the page "1" in the file "Embedded_Linux_Code.pdf". Run "focserver -p" to see the list of register names. It is also possible to add this function to the web UI; see the documentation of the network API in the file "Network_API.pdf".

The HLS project uses exactly the same focserver and web UI as the SDSoC project.

shivang1993

Thanks Andrei for such a detailed answer. Actually I am using a different motor. Therefore I had to modify the CPR value and the sin cos table.

Using Vivado HLS, I generated the IP cores for Park Direct and Park Inverse with the modified sincostable.h file. Unfortunately when I try to use the IP cores in Vivado, the ap_start port seems to be missing from both Park Direct and Park Inverse IP cores. This leads to a critical warning as well. Do you have an idea as to why this might be happening? I use the regular process of C synthesis and RTL export in Xilinx Vivado HLS.

I understood that the boot.bin file should be generated and kept on the SD card. Will it still be possible to use ILA for debugging purpose using the JTAG connection?

Thanks

Oleksandr Kiyenko

Hello,

control interface presence is controlled by a
#pragma HLS INTERFACE
directive in your cpp file. If you have something like
#pragma HLS INTERFACE ap_ctrl_none port=return
control signals, like ap_start will be not generated by Vivado HLS

Best regards
Oleksandr Kiyenko

Andrei Errapart

Quote from: shivang1993 on August 05, 2019, 04:50:49 AM
I understood that the boot.bin file should be generated and kept on the SD card. Will it still be possible to use ILA for debugging purpose using the JTAG connection?
Yes. The ILA can be used regardless the way FPGA got its configuration.

shivang1993

Hello Oleksandr and Andrei,

I did not change anything in any of the .cpp file. So there is no #pragma HLS INTERFACE ap_ctrl_none port=return in any of he files. While generating the IP Core in Vivado Hls, I can see the ap_start in the interfaces but as soon as I export it to Vivado, only that port disappears. However I found a workaround by following the issue on https://www.xilinx.com/support/answers/63035.html. So I have set the ap_start to be 1 in the IP Packager.

There is another issue which is arising now. I followed the process mentioned on (https://wiki.trenz-electronic.de/display/PD/Project+Delivery#ProjectDelivery-Reference-Design:GettingStarted) to create the project and changed the design_basic_settings_cmd appropriately. Although when the project got created, it took Arty-Z7-20 files instead of Arty-Z7-10. I modified the project part back to Arty-Z7-10 under Project Manager --> Setting --> Project part and ran the command TE::hw_build_design -export_prebuilt. The synthesis went through but there was an error in implementation:

[Project 1-686] The current project part 'xc7z010clg400-1' does not match with the sub-design 'zsys.bd' part 'xc7z020clg400-1'. Please open this sub-design in original project and generate with matching parts before adding it to current netlist project.

How can I change the project part for this sub-design?

I also tried to generate the files using the default Ary-Z7-20 board files but they did not run on the Arty-Z7-10 board. Also the command TE::hw_build_design -export_prebuilt did not generate any BOOT.bin file. It only generated the .bit file and some other files. But when I ran TE::hw_build_design followed by TE::sw_run_hsi, I was able to generate the BOOT.bin file

Thanks

JH

Hi,
Quoteto create the project and changed the design_basic_settings_cmd appropriately. Although when the project got created, it took Arty-Z7-20 files instead of Arty-Z7-10.

can you do the project generation again:
1. open  "design_basic_settings_cmd" on the basefolder with text editor and set on line 36: @set PARTNUMBER=1
2. run  "vivado_create_project_guimode.cmd" and send me the log file, which is located in /v_log/vivado.log

br
John


shivang1993

Hi John,

I was able to get rid of the error. Actually I was changing the value of PARTNUMBER in line 35 and not in 36. When I changed in Line 36 as well, I was able to get the correct board and generate the .bit file without any issues. Thanks for the help.