NI MATRIXx AutoCode Reference TM AutoCode Reference April 2007 370768C-01 TM
Support Worldwide Technical Support and Product Information ni.
Important Information Warranty The media on which you receive National Instruments software are warranted not to fail to execute programming instructions, due to defects in materials and workmanship, for a period of 90 days from date of shipment, as evidenced by receipts or other documentation. National Instruments will, at its option, repair or replace software media that do not execute programming instructions if National Instruments receives notice of such defects during the warranty period.
Conventions The following conventions are used in this manual: <> Angle brackets that contain numbers separated by an ellipsis represent a range of values associated with a bit or signal name—for example, DIO<3..0>. » The » symbol leads you through nested menu items and dialog box options to a final action. The sequence File»Page Setup»Options directs you to pull down the File menu, select the Page Setup item, and select Options from the last dialog box.
Contents Chapter 1 Introduction Manual Organization .....................................................................................................1-1 General Information.......................................................................................................1-2 Configuration File..........................................................................................................1-2 Language-Specific Information .......................................................................
Contents Linking Procedures with Real-Time Applications or Simulator .................... 2-22 Invoking Generated Procedures Directly.......................................... 2-22 Invoking Procedures Using Generated UCB Wrapper Function...... 2-24 Invoking Procedures Using Generated Subsystem Function ........... 2-25 C Fixed-Point Arithmetic .............................................................................................. 2-26 Fixed-Point AutoCode/C Implementation ...........................
Contents External_Input ( ) Procedure.............................................................3-10 External_Output( ) Procedure ...........................................................3-11 UserCode Blocks ...........................................................................................................3-11 Linking Handwritten UCBs with AutoCode Applications..............................3-11 Calling UCBs.........................................................................................
Contents Chapter 4 Generating Code for Real-Time Operating Systems Real-Time Operating System Configuration File.......................................................... 4-1 Configuration Items ........................................................................................ 4-2 Table Syntax ................................................................................................... 4-2 Table Naming Convention................................................................
Contents System External Interface Layer .....................................................................5-7 Discrete Subsystem Interface Layer................................................................5-8 Single-Rate System ...........................................................................5-8 Multi-Rate System ............................................................................5-8 Sample and Hold ...............................................................................
Contents States ............................................................................................................... 5-26 Local Variables and Phases .............................................................. 5-27 Discrete Semantics ........................................................................... 5-27 Continuous Semantics ...................................................................... 5-29 Looping Concepts .....................................................................
Contents Definitions and Conventions ...........................................................................5-45 Shared Memory Fixed-Point Callouts in AutoCode/C .....................5-46 Shared Variable Block Support .......................................................................5-47 Shared Memory Callout Option ........................................................5-50 Global Variable Block Callouts.......................................................................5-51 Callout Pairs....
Contents Chapter 7 Code Optimization Read from Variable Blocks ........................................................................................... 7-1 Restart Capability .......................................................................................................... 7-5 Merging INIT Sections.................................................................................................. 7-8 Reuse of Temporary Block Outputs .................................................................
Contents Variable Block Aliasing....................................................................9-4 Monitored Signals within a Procedure SuperBlock ..........................9-4 Monitoring Procedure External Outputs ...........................................9-4 Parameterless Procedure ................................................................................................9-5 Specifying Parameterless Procedure Interface ................................................9-5 Input Specification ...
1 Introduction This manual provides reference material for using AutoCode to write production quality code using graphical tools. Together with the AutoCode User Guide and the Template Programming Language User Guide, AutoCode documentation describes how to generate robust, high-quality, real-time C or Ada source code from SystemBuild block diagrams.
Chapter 1 Introduction • Chapter 8, AutoCode Sim Cdelay Scheduler, discusses the Sim Cdelay low-latency scheduler. • Chapter 9, Global Scope Signals and Parameterless Procedures, discusses additional signals and procedures. This guide also has an Index. General Information As an integral part of the rapid prototyping concept, AutoCode lets you generate high-level language code from a SystemBuild block diagram model quickly, automatically, and without programming skills.
Chapter 1 Introduction Structure and Content of the Generated Code This reference includes detailed descriptions about what is generated for many of the blocks used within a model. Also, the framework of the generated code is discussed to show how all of the pieces work together to form an executable simulation. This discussion is only relevant to those designers who are either writing their own templates or who are striving to optimize the generated code.
Chapter 1 Introduction Related Publications National Instruments provides a complete library of publications to support its products.
C Language Reference 2 This chapter discusses files used to interface AutoCode and the generated C code to your specific platform and target processor. This chapter also describes target-specific utilities needed for simulation and testing. Stand-Alone Simulation The template provided for C code generation produces code that, when compiled and linked with stand-alone files, forms a stand-alone simulation.
Chapter 2 C Language Reference Table 2-1. Recognized C Preprocessor Defines for Supported Platforms Platform Preprocessor Define Compiler Switch AIX (IBM UNIX) IBM -DIBM Compaq Tru64 5.0 OSF1 -DOSF1 HPUX (700 series) HP700 -DHP700 HPUX (other than 700) HP -DHP SGI IRIX SGI -DSGI Sun Solaris 2.x SOLARIS -DSOLARIS Windows 2000/NT/9x MSWIN32 -DMSWIN32 Stand-Alone Library This section describes the system-specific and target-specific stand-alone (sa) files supplied with your system.
Chapter 2 C Language Reference Table 2-2. Distribution Directories and Files (Continued) Platform UNIX Windows Templates Directory: Templates: Direct Access Templates: $CASE/ACC/templates c_sim.tpl, c_intgr.tpl c_sim.dac %CASE%\ACC\templates c_sim.tpl, c_intgr.tpl c_sim.dac Demos Directory: $XMATH/demos %XMATH%\demos • • The principal file is sa_utils.c, the stand-alone utilities file. At the time that you compile sa_utils.
Chapter 2 C Language Reference Table 2-3. Header Files File Purpose sa_sys.h Defines the development platform. Contains a C preprocessor #define statement for each supported platform. sa_types.h Defines the supported data types and certain math constants. sa_defn.h Defines constants for generated code, error codes, and mapping for ANSI features such as const and volatile. sa_intgr.
Chapter 2 C Language Reference to. For example, RT_INTEGER can be redefined as long int if arithmetic overflow becomes a problem on a given platform. Target-Specific Utilities Target-specific utilities (in sa_utils.c) perform hardware, application, and C-specific tasks that are required for simulation and testing. They can be modified to support the generated code on different target computers.
Chapter 2 C Language Reference Table 2-4. Target-Specific Utility Routines (Continued) Routine Description Implementation_Terminate( ) Perform implementation-specific termination tasks. External_Input( ) Collect external inputs. External_Output( ) Post external outputs. Signal_Remote_Dispatch( ) Multiprocessor implementations only; signal secondary processors that a dispatch table is available. The sa_utils.
Chapter 2 C Language Reference Two error functions are provided, fatalerr( ) and error( ). The fatalerr( ) function reports exception conditions detected by the functions in the sa_utils.c file. error( ) reports conditions detected by the generated code during execution. Not all reported conditions are errors. These functions can be invoked for deactivating all necessary functions and then passing an alarm to the external environment or for initiating recovery action.
Chapter 2 C Language Reference the comments there and adjust the limits accordingly, then recompile and relink the sa_utils.c file. ERROR OPENING THE INPUT FILE ERROR OPENING THE OUTPUT FILE A problem was encountered opening the input or output file. Possible causes include a file protection violation. UNKNOWN ERROR A value of the ERROR variable occurred that was not one of those defined for the switch-case statement. Check any error indications you may have introduced.
Chapter 2 C Language Reference Implementation_Initialize( ) Function void Implementation_Initialize (RT_FLOAT *BUS_IN RT_INTEGER, NI, RT_FLOAT BUS_OUT, RT_INTEGER NO, RT_FLOAT SCHEDULER_FREQ); In the default version of sa_utils.c (simulation comparison), this function initializes the I/O for the system by loading input data from the user-furnished MATRIXx FSAVE input file.
Chapter 2 C Language Reference External_Input ( ) Function RT_INTEGER External_Input(void) External_Input( ) is for use in the simulation comparison mode; it reads in external input data from your specified FSAVE input file. The data appears in XINPUT, an array of type RT_FLOAT, dimensioned equal to the input vector (T- and U-vectors) defined at simulation time. No data conversion is required in this version of the generated code, because all data is passed as arrays of type RT_FLOAT.
Chapter 2 C Language Reference Linking Handwritten UCBs with AutoCode Applications To write code for UserCode Blocks (UCBs), refer to the sa_user.c file, which is provided in your src distribution directory. The sa_user.c file contains an example of a UCB function declaration (refer to the Implementing Handwritten UCBs section). If your model has more than one UCB, each prototype must have a unique name.
Chapter 2 C Language Reference 1 2 Figure 2-1. Example UserCode Function File (sa_user.c) The $ucb directive is recognized and interpreted by the automatic linking facility of the simulator in SystemBuild to distinguish between UCBs written for simulation purposes using SystemBuild only and UCBs written for linking with AutoCode applications. The exact name of the UCB function must be specified in the $ucb directive if this UCB function is used for simulation using SystemBuild.
Chapter 2 C Language Reference Implementing Handwritten UCBs Arguments are passed for each call to the UCB in the following order: INFO, T, U, NU, X, XDOT, NX, Y, NY, R_P, and I_P Pointers to all of the arrays (U, X, XD, Y, R_P, I_P) and scalers corresponding to array sizes (NU, NX, NY) are passed to each call to the UCB. The sizes of R_P and I_P arrays must be entered into the UCB dialog to ensure that proper storage is allocated by the caller.
Chapter 2 C Language Reference The operations within UCBs are controlled by the argument INFO, a pointer to a structure of type STATUS_RECORD that is passed as part of the argument list for each UCB (located in sa_types): typedef struct STATUS_RECORD { RT_INTEGER ERROR; RT_BOOLEAN INIT; RT_BOOLEAN STATES; RT_BOOLEAN OUTPUT; } RT_STATUS_RECORD; The following example shows the general form of UCB equations for AutoCode and indicates how the INFO status record pointer is used to control the computations.
Chapter 2 C Language Reference File Name: usr_dsp.c y (k) = -1/2*y(k-2) + 3* u(k) + u(k-2); which leads to the State-Space realization: x1(k+1) = x2(k) x2(k+1) = -1/2* x1(k) - 1/ 2*u(k) y(k) = x1(k) + 3*u (k) Generate AutoCode Application dsp.c usr_dsp.c (Handwritten UCB using sa_user .c example) compile and link Figure 2-2.
Chapter 2 C Language Reference Linking Handwritten UCBs (for AutoCode) with SystemBuild After you have written a UCB to create an AutoCode application, you can use the same UCB for simulation. SystemBuild can automatically compile and link your UserCode function into the simulation engine (release 4.0 and later). Refer to Figure 2-3. SystemBuild provides the usr01.c example file and AutoCode provides the sa_user.c example file for writing UCBs.
Chapter 2 C Language Reference simulation (automatic compiling and linking of usr_dsp.c into new UCB shared library) Fleming: usr_dsp.c Function Name: usr_dsp usr_dsp.c (Handwritten UCB using sa_user.c example) simexe.lnx Figure 2-3. Linking Handwritten UCBs with the SystemBuild Simulator The arguments to a UCB written only for linking with the SystemBuild simulator (using usr01.c) are inherently different than the arguments to a UCB written for linking with an AutoCode application (using sa_user.c).
Chapter 2 C Language Reference applications, make sure you adapt the same algorithm in the body of a function using the AutoCode UCB arguments as in sa_user.c. Variable Interface UCB The preceding sections described the fixed interface; however, a UCB can also use the variable interface option. For information on how to specify the variable interface option, refer to the SystemBuild User Guide.
Chapter 2 C Language Reference As previously stated, the inputs and outputs of the UCB will have the same data type as specified in the model diagram. Inputs are passed by value while outputs are passed by reference. In addition, the “shape” of an argument describes whether it is a scalar value or an array. For information on how to specify the data type and shape of the inputs and outputs of the UCB, refer to the SystemBuild User Guide.
Chapter 2 C Language Reference Linking a Variable Interface UCB with the Simulator Unlike the fixed interface which provides an automatic method for linking with the Simulator, the variable interface is too complicated for that method. As a result, you are required to create a “wrapper” function that interfaces between the Simulator and your code. For information on how to create the wrapper for the Simulator, refer to the SystemBuild User Guide.
Chapter 2 C Language Reference proc_ucb_hook. Refer to the Template Programming Language User Guide. simulation (automatic compiling and linking of myproc.c int. new UCB shared library) myproc myproc SUPER BLOCK USER CODE Procedure Procedure 1 myproc Generate Reusable Procedure 4 Filename: myproc.c Function Name: myproc_ucbhook (name of procedure SuperBlock with _ucbhook appended to it) myproc.c 2 simexe.lnx 3 Figure 2-4.
Chapter 2 C Language Reference Linking Procedures with Real-Time Applications or Simulator Generate reusable procedures from your Procedure SuperBlocks as described in this chapter and in Chapter 3, Ada Language Reference. To link generated reusable procedures with your own application or simulator you have the three following options: • Invoke the generated algorithmic procedure directly (refer to callout 2 of Figure 2-4), passing it pointers to structure objects as arguments.
Chapter 2 3. C Language Reference Create an object of type _procedure name_s where the states of the procedure will be stored and initialize all members of the object to 0.0. This should be done during initialization only. A pointer to this object will be passed as argument S to the procedure. Generate Reusable Procedure Figure 2-5. Arguments to Generated Procedure proc 4.
Chapter 2 C Language Reference point to the appropriate global variables. A pointer to this object will be passed as argument I to the procedure. 5. Invoke the procedure using pointers to the objects created in steps 1 through 4. 6. Toggle the state flag of the states object of the procedure—that is, if the value is 0 toggle it to 1, if the value is 1 toggle it to 0—before calling the procedure again.
Chapter 2 C Language Reference properly. Refer to the SystemBuild User Guide for an explanation of rinfo. Only the first four elements of this array will be used by the generated procedure. This array will be passed as argument rinfo. 3. Create an array sized by the number of inputs in the procedure (refer to the comment) of type double and copy in the inputs to the procedure. This array will be passed as argument U.
Chapter 2 C Language Reference data-typed variables reflecting each subsystem input signal and type. The outputs to the subsystem are provided by the argument Y, a pointer to a structure named _Subsys_number_out. This structure has mixed data-typed variables reflecting each subsystem output signal and type. The following overall steps need to be taken to invoke the subsystem function: 1. Create an object of type _Subsys_1_in (see generated subsystem code) and copy in the inputs to the subsystem.
Chapter 2 C Language Reference number—for each integer item and the sign are managed by the code generator. Arithmetic expressions are scaled to emulate a fixed-point capability, and all expressions involving the item are coded to be consistent with the chosen radix position. AutoCode supports a fixed-point library that implements all of the fixed-point operations (algebraic, relational, conversion). There are two different interfaces to the fixed-point library.
Chapter 2 C Language Reference language and replace the supplied macros (or functions) with your (assembly) functions so that you can take full advantage of the processor’s arithmetic capabilities.
Chapter 2 C Language Reference Table 2-6.
Chapter 2 C Language Reference RT_SSHORT05 SS5; RT_SSHORT SS0; RT_SSHORT05 SS5_1; }; struct _Sys_ExtIn { RT_USHORT13 US13; RT_SSHORT14 SS14; }; /******* System Ext I/O type definitions. *******/ struct _Subsys_1_out subsys_1_out; struct _Sys_ExtIn sys_extin; static RT_FLOAT ExtIn [NUMIN+1]; static RT_FLOAT ExtOut [NUMOUT+1]; /******** Procedures’ declarations ********/ /******* Procedure: proc *******/ /***** Inputs type declaration.
Chapter 2 C Language Reference The UTs appear as typedef statements in the generated C code. For example: typedef volts RT_SBYTE03; This code defines the data type called volts to be a signed byte with radix position 3. Overflow Protection Overflow is defined as loss of significance—that is, a computation losing bits in the integer part of the number. The term underflow is used to mean overflow on a negative number. An Overflow Protection capability is provided to protect against overflows.
Chapter 2 C Language Reference Macro Interface The macro interface files are: AutoCode Reference sa_types.h Updated to include fixed-point types. sa_fx.h Contains fixed-point conversion macros. sa_fxp.h Contains fixed-point conversion macros with overflow protection. sa_fxr.h Contains fixed-point relational macros. sa_fxm.h Contains fixed-point arithmetic macros. sa_fxmp.h Contains fixed-point arithmetic macros with overflow protection.
Chapter 2 sa_fx_externs.c C Language Reference Contains definitions for extern variables such as mask buffers that are read only. Function Interface The function interface files are: sa_types.h Updated to include fixed-point types. sa_fxp.h Contains fixed-point conversion macros with overflow protection. sa_fxr.h Contains fixed-point relational macros. sa_fxm.h Contains fixed-point arithmetic macros. sa_fxmp.h Contains fixed-point arithmetic macros with overflow protection.
Chapter 2 C Language Reference sa_fxsub_byte.c Contains fixed-point subtraction functions for byte data type. sa_fxsub_short.c Contains fixed-point subtraction functions for short data type. sa_fxsub_long.c Contains fixed-point subtraction functions for long data type. sa_fxmul_byte.c Contains fixed-point multiplication functions for byte data type. sa_fxmul_short.c Contains fixed-point multiplication functions for short data type. sa_fxmul_long.
Chapter 2 C Language Reference Fixed-Point Conversion and Arithmetic Macros Although this section explains different fixed-point operations in terms of macros, all of these operations are supported as functions in the function interface. Hence, in the following sections the term macro can be completely substituted by the term function. Three types of fixed-point macros are generated by AutoCode: • Conversion macros that convert one type of number to another. Refer to the Conversion Macros section.
Chapter 2 C Language Reference Figures 2-6 through 2-8 show how the conversion macros are named. Notice that macro names have no embedded spaces.
Chapter 2 C Language Reference i ALIGN so wo p (n, rp) n = Fixed-point operand to align rp = Number of bits to shift (if rp < 0, perform a left-shift; if rp > 0, perform a right-shift) p = Overflow protection (optional) wo = Operand wordsize (b=byte, s=short, l=long) so = Operand sign (u=unsigned, s=signed) ALIGN (indicates conversion) i = Indicates integer result Figure 2-7.
Chapter 2 C Language Reference Arithmetic Macros The arithmetic macros perform addition, subtraction, multiplication, and division. The top level macros for arithmetic operations are present in the sa_fxm.h and sa_fxmp.h files. These macros in turn call the ALIGN macros that are defined either in sa_fx.h or sa_fxp.h, depending on whether or not they are overflow protected. The macros for addition and subtraction also make use of addition and subtraction functions defined in sa_fxmp.c.
Chapter 2 C Language Reference Table 2-7 shows permissible operand and result sizes for the arithmetic macros. Table 2-7.
Chapter 2 C Language Reference Implementation of the Addition and Subtraction Macros AutoCode has two implementations of the addition and subtraction macros: • Macros that apply wordsize extension (also called extended intermediate types) to the two operands before aligning the radix positions and adding or subtracting. This is the default implementation. Wordsize extension provides greater accuracy, but is slower because the operations are performed in a larger wordsize than specified.
Chapter 2 C Language Reference Align the radix positions of n1 and n2 to the radix position of the result before subtracting (that is, shift n1 left by three bits, and shift n2 left by two bits). Place the aligned results in n1' and n2' and perform a 16-bit subtraction of n1' and n2', and store the result in n3': 00000000 1^0001000 (n1' = (136,r7), decimal value = 1.0625) — 00000000 1^0000000 (n2' = (128,r7), decimal value = 1.0) _______________________ 00000000 0^0001000 (n3' = (8,r7), decimal value = .
Chapter 2 C Language Reference 0^1111111 (n2' = (127,r7), decimal value = .9921875) ___________ 0^0000000 (n3 = (0,r7), decimal value = 0.0) In Example 2-3, method 1 is more accurate than method 2, but it is also less efficient because it involves a 16-bit subtraction. This is important for those using 8-bit processors but will probably not be as significant for those using 16-bit or 32-bit processors.
Chapter 2 C Language Reference the maximum possible value representable in 32 bits—is returned. This multiplication process can be expensive because it involves several multiplication and addition operations to produce an intermediate result. This procedure strives for accuracy, but a user can speed up the process by giving up some of the accuracy. 32-Bit Division As with 32-bit multiplication, operands are split into higher and lower words.
Chapter 2 C Language Reference in terms of speed, but is needed to compute an accurate result. By changing this behavior, you can speed up the operation if you are willing to give up some accuracy. For more information on the implementation of multiplication and division macros, refer to the SystemBuild User Guide. Note Fixed-Point Relational Macros The relational macros compare two numbers and return a Boolean result (true or false). Macros for relational operations are defined in sa_fxr.h.
Chapter 2 C Language Reference For example, the macro to check an 8-bit unsigned number and an 8-bit signed number for equality and produce a Boolean result is: boolEQ_ub_sb(n1,n2,rp1,rp2) Some Relevant Issues • The fixed-point macros used by AutoCode-generated files are defined in the sa files and are available to you for making modifications. If the AutoCode macros are changed, the results might not match the Sim results.
Ada Language Reference 3 This chapter discusses files used to interface AutoCode and the generated Ada code to your specific platform and target processor. This chapter also discusses target-specific utilities needed for simulation and testing. Stand-Alone Simulation The templates provided for Ada code generation produce code that, when compiled, form a stand-alone simulation. This simulation can be executed with MATRIXx data as input, and produces results that can be loaded back into Xmath for analysis.
Chapter 3 Ada Language Reference Table 3-1. Identified Ada Run-Time Versions of the Stand-Alone Library Platform Stand-Alone Library Solaris, UNIX Verdix HP-UX/DOS Alsys Windows 2000/NT/9x/DOS ActivAda Supplied Templates ada_rt.tpl Template The ada_rt.tpl template is the default when generating Ada code. This template uses Ada tasks to implement the scheduling mechanism for the model. This template supports fixed-point arithmetic. ada_sim.tpl Template The ada_sim.
Chapter 3 Ada Language Reference Stand-Alone Library This section describes the system-specific and target-specific stand-alone (sa_*) files supplied with your system. System-Specific Files Header and source files are supplied to interface AutoCode generated code to your development platform, and to the target processor in your test bed or rapid-prototyping system. Both specifications and the source files are provided in your source directory: • Specification files have the suffix _.a or _.
Chapter 3 Ada Language Reference Table 3-2. Distribution Directories and Files (Continued) Category Templates UNIX Windows Directory: Directory: %CASE%\ACA\templates $CASE/ACA/templates Templates: ada_rt.tpl, Templates: ada_rt.tpl, ada_intgr.tpl, ada_sim.tpl ada_intgr.tpl, ada_sim.tpl Compiled Template: ada_rt.dac, ada_sim.dac Compiled Template: ada_rt.dac, ada_sim.dac Demos Directory: $XMATH/demos • • • The principal file is sa_utils.a (or sa_utils.ada), the stand-alone utilities file.
Chapter 3 Ada Language Reference floating-point MATH_LIB. The sa_time.a/.ada file provides the Elapsed_Time_Of( ) function. The purposes of the more important specification files are listed in Table 3-3. . Table 3-3. Target-Specific Utility Routines File Purpose sa_types_.a Defines the supported data types. sa_defn_.a Defines constants and error codes for generated code. sa_utils_.a Defines external function prototypes for the stand-alone utilities. sa_math_.
Chapter 3 Ada Language Reference Target-Specific Utilities The target-specific utilities in the sa_utils.a or sa_utils.ada file perform hardware-, application-, and Ada-specific tasks that are required for simulation and testing. They can be modified to support the generated code on the target computer. As furnished, these routines simulate I/O operations that would occur in a simulation environment, using import files created using MATRIXx.
Chapter 3 Ada Language Reference Table 3-4. Target-Specific Utility Routines (Continued) Routine Function External_Output( ) Post external outputs. Signal_Remote_Dispatch( ) Multiprocessor implementations only; signal secondary processors that a dispatch table is available. The sa_utils.a or sa_utils.ada file contains comments about each of the routines as they are used for comparing simulation with generated code results.
Chapter 3 Ada Language Reference Refer to the Chapter 14, UserCode Blocks, of the SystemBuild User Guide or the source listing of the USR01 routine for meanings of UCB errors. You are allowed to extend the scope of these messages, so it might be one of yours. Unknown error encountered in task n A possible cause is an incorrect user-written error condition in the generated code. Time overflow occurred in task n This indicates a subsystem (or task) overflow.
Chapter 3 Ada Language Reference By default, several error conditions are trapped in the procedure Implementation_Initialize of sa_utils.a/.ada, but you can expand this capability in your own versions of the program, detecting your own error conditions and adding your own messages. The Ada exception processing facility is used and you are encouraged to define and raise exceptions in your versions of the Implementation_Initialize procedure.
Chapter 3 Ada Language Reference These messages indicate that the sizes of the time vector and input array have exceeded one or more of the storage allocation size limits established by sa_utils.a/.ada. These limits are established as constants at the very beginning of the stand-alone utilities file, just after the trademark notice. Refer to the comments in the file and adjust the limits accordingly; then recompile and relink the utilities file.
Chapter 3 Ada Language Reference External_Input( ) is much the same; it returns an input vector from the software data bus. External_Input( ) returns the value of SCHEDULER_STATUS, which is passed to it by the scheduler. External_Output( ) Procedure procedure External_Output(Bus: in RT_REAL_ARRAY; YE_PTR: in RT_INTEGER; NUMOUT: in RT_INTEGER; SCHEDULER_STATUS: out INTEGER) External_Output is for use in simulation comparison mode. It places output data values into an output pool in memory.
Chapter 3 Ada Language Reference Calling UCBs Every one of the following arguments will be passed for each call to the UCB in the following order: INFO, T, U, NU, X, XD, NX, Y, NY, R_P, I_P Within the UCB, the elements of all the array variables (U, X, XD, Y, R_P, I_P) must be accessed as in the following example: U(U'first), U(U'first+1), ... U(U'first+NU-1) X(X'first), X(X'first+1), ... X(X'first+NX-1) Make sure to access the elements in the above manner as all the arrays are passed as array slices.
Chapter 3 Ada Language Reference Table 3-5. UCB Calling Arguments and Data Types (Continued) Argument Data Type Description I_P:in out RT_INTEGER An array of integer parameters. NIP:in out RT_INTEGER The number of integer parameters.
Chapter 3 Ada Language Reference Procedure SuperBlocks This section describes how to generate and link Procedure SuperBlocks. Generating Reusable Procedures Generate reusable procedures from your Procedure SuperBlocks as described in Chapter 2, Using AutoCode, of the AutoCode User Guide.
Chapter 3 Ada Language Reference ------------------------------------------------------------------------ Wrapper around the procedure to support UCB (Fixed calltype) interface -- This routine can be called as a UCB either from SystemBuild or AutoCode ---------------------------------------------------------------------------------------------------------------------------------------------- Map -- ---- Number of Inputs: 2 -- Number of Outputs: 3 -- Number of States: 0 -- Number of Integer parameters: 0 -
Chapter 3 Ada Language Reference Ada Fixed-Point Arithmetic This section describes the implementation of fixed-point arithmetic in AutoCode/Ada. It is assumed that you are familiar with the Ada programming language. The SystemBuild User Guide has a fixed-point arithmetic chapter that explains the basics of fixed-point arithmetic and the use of fixed-point arithmetic in SystemBuild models. Note How to Generate Real-Time Code Using AutoCode, you can generate Ada high-level language code.
Chapter 3 Ada Language Reference Fixed-Point Data Types Fixed-point type declarations exist in the file named: sa_fxptypes_.a and is provided in the System-Specific Files src (source) directory.1 This file contains the specification of the SA_FIXED package. The package specification contains all of the type declarations with the appropriate delta and range for each type. Refer to the AutoCode Reference for more information about the fixed-point type sizes, radix ranges and naming conventions.
Chapter 3 Ada Language Reference Package Dependencies The fixed-point AutoCode/Ada architecture forces a dependency among the supplied and generated code for a model that uses any fixed-point types. This dependency affects compilation order within an Ada Library. Figure 3-1 illustrates the imposed dependency. In the figure, a package that is beneath a package and connected to a package above it by an arrow is said to be dependent on the package that is above.
Chapter 3 Ada Language Reference Generated Code with Fixed-Point Variables Fixed-point arithmetic operations are accomplished by overloading the standard arithmetic operators for the fixed-point types. Therefore, the generated code with fixed-point variables uses the same infix expressions that non-fixed-point variables normally use, except for the following modifications: • The package name must be used when referring to a fixed-point type.
Chapter 3 Ada Language Reference System-Level Parameters to Generate User Types Table 3-6 describes new system-level parameters that are used to generate the USER_TYPES package. Table 3-6. System-Level Parameters to Generate User Types Name Description n_user_defined_type_i The number of user types in the current model. usertype_name_ls An array of strings that contain the names of all of the user types in the model. Array size is n_user_defined_type_i.
Chapter 3 Ada Language Reference frequently overflowing, a different data type should be selected. If you are concerned about performance and the use of an exception handler for detecting overflow, the generic functions can be changed. These changes do not affect the generated code in any way. Thus, you can freely modify the generic function implementations without having to regenerate the model.
Chapter 3 Example 3-2 Ada Language Reference 1. Build a model—Use the SuperBlock Editor to construct a model that uses fixed-point types for input/output signals. Refer to the SystemBuild User Guide for more information. 2. Generate real-time code—From the SystemBuild pull-down menus, select Build»Generate Real-Time Code. In the AutoCode dialog box, select Ada Code Generation and continue. Example 3-2 shows a sample transcript that should appear in the Xmath window during code generation.
Chapter 3 Ada Language Reference 4. Compile the generated files—Two source files are generated, gaintest.a and fxp_gaintest_.a, as shown in Figure 3-1. The imposed package dependencies (refer to the Package Dependencies section) require that the RT_FIXED_OPERATORS package be compiled into the Ada Library before the code that represents the model. Thus, the file fxp_gaintest.a is compiled before gaintest.a. 5. Create an executable—This is the final step and it creates an executable file.
Chapter 3 Ada Language Reference Table 3-9. Generic Function Summary Function Name AutoCode Reference Purpose FIXED_ADD Addition of two fixed-point values. FIXED_SUB Subtraction of two fixed-point values. FIXED_MUL Multiplication of two fixed-point values. FIXED_DIV Division of two fixed-point values. FIXED_IDENTITY The identity property of a fixed-point value. SIGNEDNEGATION Negation for a value of a signed fixed-point type.
Chapter 3 Ada Language Reference Table 3-9. Generic Function Summary (Continued) Function Name Purpose Fixed-point value to LONGINTCAST RT_LONG_INTEGER conversion. LONGINTCAST_TRUNC Fixed-point value to RT_LONG_INTEGER conversion using truncation. LONGINTCAST_ROUND Fixed-point value to RT_LONG_INTEGER conversion using rounding. Fixed-point value to RT_BOOLEAN conversion. BOOLEANCAST RT_INTEGER to a fixed-point type INTFIXEDCAST conversion.
Chapter 3 Ada Language Reference Bit-Wise Functions A restricted set of bit-wise operations have been defined for certain fixed-point types. These functions exist in the SA_FIXED_BITWISE_FUNCTIONS package found in the sa_fxpbit_.a and sa_fxpbit.a files. The set of bit-wise operations are the following three functions: BTEST, BCLEAR, and BSET. BTEST tests the nth bit of a value. BCLEAR clears the nth bit of a value. BSET sets the nth bit of a value.
Chapter 3 Ada Language Reference Conversion Function Instantiations The RT_FIXED_OPERATORS package contains instantiations of functions that represent conversion of values to and from a fixed-point type. The appropriate generic function from the SA_FIXED_GENERICS package is chosen to instantiate the function. The name of the instantiated function follows a convention that indicates what type of conversion is to be done. Table 3-10 defines the naming convention for conversion functions. Table 3-10.
Chapter 3 Ada Language Reference Sample Package Example 3-3 shows a generated RT_FIXED_OPERATORS package. Example 3-3 Generated RT_FIXED_OPERATORS Package ---------------------------------------------------------------------------AutoCode/Ada (TM) Code Generator 7.X --National Instruments Corporation, Austin, Texas ----------------------------------------------------------------------------- rtf filename : feed.rtf -- Filename : fxp_feed_.a -- Dac filename : ada_sim.
Chapter 3 Ada Language Reference function “>=” is new SA_FIXED_GENERICS.GREATEREQUAL(SA_FIXED.RT_SSHORT14, SA_FIXED.RT_SSHORT08); --pragma inline (">="); function ">=" (LEFT, RIGHT : SA_FIXED.RT_SSHORT13) return BOOLEAN renames SA_FIXED.">="; --pragma inline (">="); function RT_US11 is new SA_FIXED_GENERICS.FLOATFIXEDCAST(SA_FIXED.RT_USHORT11); --pragma inline (RT_US11); -- Conversion Function Instantiations -function RT_US13r is new SA_FIXED_GENERICS.FLOATFIXEDCAST_ROUND(SA_FIXED.
Chapter 3 Ada Language Reference The selection of the intermediate type is performed by the code generator. The selection involves a set of rules that rely upon word size extension. Word size extension is selecting a fixed-point type with a larger number of bits that can be used to represent model numbers. Also, the radix of the intermediate type is chosen to be the radix of the result fixed-point type.
Chapter 3 Ada Language Reference Multiplication and Division Functions The predefined multiplication and division operators for fixed-point type based arguments are defined in Ada for any combination of fixed-point arguments. The result of the computation is exact and of arbitrary accuracy. Thus, a conversion to the result type of the expression must be performed. During this conversion, accuracy might be lost.
Chapter 3 Ada Language Reference no chance of overflow. To support these issues there are three types of conversion functions: • Language-defined conversion • Truncation conversion • Explicit rounding conversion These conversions are described in the following sections. Language-Defined Conversion The Ada language provides four data type conversions. The rules in Ada that govern the conversion are explicit except for one detail.
Chapter 3 Ada Language Reference For these types of conversions, the language-defined conversion is used. In general, when an explicit conversion is required and there is no specification of which to choose, AutoCode/Ada will select the explicit rounding conversion. Using System-Level Parameters to Generate Instantiations Before you can use the system-level parameters to generate operator or conversion instantiations, all of the subsystems and procedures must be generated.
Chapter 3 Ada Language Reference The data in the sp_fxp parameters represent the operators and conversion used in the currently scoped subsystem or procedure. No assumptions can be made about the order within a given list parameter. However, the nth element in one list does relate to the nth element in another list, depending on the purpose of the lists. For the sp_fxp_operatorid_li and sp_fxp_conversionid_li parameters, these contain the type of operator or conversion to be instantiated.
Chapter 3 Ada Language Reference Known Ada Compiler Problems The architecture of AutoCode/Ada Fixed-Point heavily relies upon overloaded operators and generic function instantiation. For a large and complex model, the number of overloads and instantiations might overwhelm some older Ada compilers. Also, problems might occur when compiling source code from many different models into the same Ada Library. NI suggests that code from different models be compiled into separate libraries.
Chapter 3 Ada Language Reference Table 3-11. Possible Midpoint Round Modes Mode INTEGER(5.5) INTEGER(–6.5) Toward 0 5 –6 Away from 0 6 –7 Positive Infinity 6 –6 Negative Infinity 5 –7 To Odd 5 –7 To Even 6 –6 • Floating-Point Textual Representation—The values generated from a stand-alone simulation are converted to a textual (ASCII) representation. That representation in textual form might not quite be as accurate as possible.
Chapter 3 Example 3-6 Ada Language Reference Example Code Causing Ambiguous Selection of Overloaded Operators function "*" (left:SB0; right:SB1) return SL0; function "*" (left:SB0; right:SB1) return SS0; function "*" (left:SL0; right:SL0) return SL0; function "*" (left:SS0; right:SL0) return SL0; function TO_SLO (left:SL0) return SL0; V1 : SB0; V2 : SB1: VL:SL0; begin VL := V1 * V2 * VL --ambiguous VL := TO_SL0(V1 * V2) * VL; --unambiguous expression end; The first assignment is ambiguous because there
4 Generating Code for Real-Time Operating Systems This chapter describes the RTOS configuration file and functionality provided for generating code for real-time operating systems. Real-Time Operating System Configuration File Code that is to execute under the control of a real-time operating system (RTOS) usually has configuration elements specific to the real-time environment that are not required for stand-alone code.
Chapter 4 Generating Code for Real-Time Operating Systems Configuration Items The following is a list of configuration attributes for each type of AutoCode component.
Chapter 4 Generating Code for Real-Time Operating Systems Table Naming Convention Tables are given a name to identify the contents of the data contained therein. Table names are specified in the same form as Xmath variables, partition.name. RTOS does not look at the partition specifier. Notice that the name specifier is case sensitive. Table Column Contents The contents of a column within a table has a specific data type—for example, an integer or floating point or string value.
Chapter 4 Generating Code for Real-Time Operating Systems Example 4-1 Processors Table Example rtos.processors = 2 Scheduler Priority Table Table 4-2 is a single element table consisting of the priority assigned to the scheduler task. The table is named: scheduler_priority. Example 4-2 shows an example of a scheduler priority table. Table 4-2.
Chapter 4 Example 4-3 Generating Code for Real-Time Operating Systems Subsystem Table Example rtos.subsys = Subsystem | Priority Stack Size Processor Mode Flags ------------------------------------------------------------------1 | 200 4096 1 K_NOFATAL 2 | 150 4096 1 K_IO | K_ER 3 | 150 8192 2 K_STO The SystemBuild Analyzer identifies how many subsystems a particular model has. AutoCode is limited to providing you with a warning if the subsystems change.
Chapter 4 Generating Code for Real-Time Operating Systems Example 4-4 Interrupt Table Example rtos.intrsupblk = Interrupt | Priority Stack Size Processor Vector Mode Flags ---------------------------------------------------------------------catch_it | 200 4096 1 255 NONE sigio_io | 150 4096 1 127 I_IO keypad | 150 8192 2 31 NONE Background Procedure SuperBlock Table Table 4-5 consists of configuration information for all background procedure SuperBlocks in the model.
Chapter 4 Generating Code for Real-Time Operating Systems Startup Procedure SuperBlock Table Table 4-6 consists of configuration information for all startup procedure SuperBlocks in the model. Each row is identified by the name of the SuperBlock. The table is named stupsupblk. Example 4-6 shows a startup table. Table 4-6.
Chapter 4 Generating Code for Real-Time Operating Systems Example 4-7 Processor IP Table Example rtos.IPprsrmap = Processor | IP Name -------------------------------------------------------------------1 | 127.0.0.1 2 | 133.65.32.111 Version Table Table 4-8 is a single element table consisting of the version number of the format of the configuration tables. The table is named version. Example 4-8 shows a version table. Table 4-8.
Chapter 4 Generating Code for Real-Time Operating Systems configuration file is updated. Also, the updated configuration file is stored in the same directory where the generated code is placed. Refer to the -o option. Caution Comments are not preserved in the default configuration file. Use a different file and the -rtosf option if you plan to preserve the comments. You must use the template parameters as specified in the previous tables before code affected by RTOS file settings is generated.
Generated Code Architecture 5 This chapter supplies more details about the content and framework of the generated code. This includes storage usage, various procedures, specialized blocks, and subsystems. This chapter is directed toward someone writing his/her own template, interfacing generated code within a larger system, designing for optimal code size and speed, or being interested in the generated code architecture.
Chapter 5 Generated Code Architecture Signal Naming A signal in the diagram is represented as a variable in the generated code. Within the diagram, signals can have two names: a label and a name. The signal’s label can appear in the diagram while a signal’s name does not appear. If a signal has both a label and a name, AutoCode uses the name to generate the symbolic name in the generated code. If there is only a label or a name, AutoCode uses whichever one is specified.
Chapter 5 Generated Code Architecture Global Storage In a strict modular programming paradigm, global storage is strictly avoided. However, global storage can be used safely and provides significant benefits in terms of code size and speed. Traditionally, AutoCode generates code that enforces a policy of safe access to global data.
Chapter 5 Generated Code Architecture • Write-To Variable Block (ALL Addressing mode)—These blocks execute after all other types of blocks within the subsystem, procedure or sequence frame. • Read-From/Write-To Variable Block (Element/Bit Addressing modes)—These variants to access variable block information are sequenced just like any other block; that is, it is sequenced after its inputs have been computed.
Chapter 5 Generated Code Architecture Subsystems This section describes the design and operation of subsystems.
Chapter 5 Generated Code Architecture Top-Level SuperBlock The term Top-Level SuperBlock is often used. This term describes the SuperBlock that was the root of the Analyzer’s processing of the SuperBlock hierarchy into subsystems, that is, a starting point for the translation.
Chapter 5 Generated Code Architecture External Output External Input SUBSYSTEM #2 External Output Scheduler External Output SUBSYSTEM #1 System External Output External Input System External Input Scheduler External Input Figure 5-1 illustrates the interface layers. The layers are described in the subsections shown in the figure. Figure 5-1.
Chapter 5 Generated Code Architecture Discrete Subsystem Interface Layer This layer comes in two variations to allow for both an optimized and general solution. The external interface to a discrete subsystem is represented by two structures, one representing the subsystem external inputs and the other the subsystem external outputs. These structures are generically referred to as the U-structure for the inputs and Y-structure for the outputs.
Chapter 5 Generated Code Architecture This sample and hold mechanism guarantees deterministic behavior for all possible connectivities and is implemented using a technique called double buffering. Double buffering involves swapping of pointers. Static Data Within Subsystems The implementation of blocks within a subsystem might require persistent data. This data can be characterized as look-up tables, parameter information, as well as data needed to manage the scheduling of the subsystem.
Chapter 5 Generated Code Architecture Procedure Data Procedure SuperBlocks have inputs, outputs and states independent of the subsystem from which the procedure is called. This is required to properly implement the characteristics of a procedure; those characteristics include reusability and reentrancy. Therefore, for each instance of a call to a procedure SuperBlock within a subsystem, a set of static variables is created for each of the structures that describe the definition of the procedure.
Chapter 5 Generated Code Architecture system, because ordering of the outputs in a single-rate system is maintained. In a multi-rate system, duplicates can be safely eliminated because of the sample and hold mechanism. The code to perform both of these activities represent a copy from one variable to another. Error Handling The error handling within a subsystem is very simple. When an error is detected, the code goes to (or throws an exception) some error handling code.
Chapter 5 Generated Code Architecture Unrolled Interface There is another form of the procedural interface, the unrolled interface (No-UY). This interface does not use U- and Y-structures to pass the inputs and outputs. The input/output signals are passed as separate arguments to the function. • Inputs—Each input signal is passed by value to the procedure. Arguments are passed in pin order. • Outputs—Each output is passed by reference. Arguments are passed in pin order.
Chapter 5 Generated Code Architecture Note If you specify a specific partition with the %var name in the block form (that is, A.GAIN), that %var is directly used, not indirectly referenced. Example 5-1 Relevant Code to Support Partitioned %vars Within a Procedure /* Xmath variable definitions. */ VAR_FLOAT A_GAIN; VAR_FLOAT B_GAIN; /******** Procedures’ declarations ********/ /******* Procedure: foo *******/ /***** Inputs type declaration.
Chapter 5 Generated Code Architecture EXEC_ERROR: return; } /******* Subsystem 1 *******/ void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { static RT_INTEGER iinfo[4]; /***** Local Block Outputs. *****/ RT_FLOAT foo_2_1; static struct _foo_u foo_2_u; static struct _foo_y foo_2_y; static struct _foo_info foo_2_i; static struct _foo_u foo_12_u; static struct _foo_y foo_12_y; static struct _foo_info foo_12_i; struct _foo_info *foo_i; /******* Initialization.
Chapter 5 Generated Code Architecture foo_2_u.foo_1 = U->t_l_1; foo(&foo_2_u, &foo_2_y, &foo_2_i); foo_2_1 = foo_2_y.foo_2_1; iinfo[0] = foo_2_i.iinfo[0]; if( iinfo[0] != 0 ) { foo_2_i.iinfo[0] = 0; goto EXEC_ERROR; } /* ---------------------------- Procedure SuperBlock */ /* {foo.12} */ foo_12_u.foo_1 = foo_2_1; foo(&foo_12_u, &foo_12_y, &foo_12_i); Y->foo_12_1 = foo_12_y.foo_2_1; iinfo[0] = foo_12_i.iinfo[0]; if( iinfo[0] != 0 ) { foo_12_i.
Chapter 5 Generated Code Architecture mixed data-typed variables reflecting each procedure output signal and type. The states of the procedure are provided by the argument S, a pointer to a structure named _procedure name_s. This structure contains the double-buffered private states used in the procedure, a flag to toggle the private states from one buffer to another, and the states structures of all procedures nested in the procedure.
Chapter 5 Generated Code Architecture Table 5-1. Description of Element iinfo in Structure _procedure name_info Array Element Description iinfo[0] Error flag. iinfo[1]=1 INIT mode. Initialize. iinfo[2]=1 STATE mode. Compute state derivatives. iinfo[3]=1 OUTPUT mode. Compute outputs in Y. Note: iinfo is an array of RT_INTEGER containing status and control flags. Table 5-2.
Chapter 5 Generated Code Architecture Extended Procedure Information Structure The -epi option specifies that additional elements to all standard procedure SuperBlock’s info structure are to be generated. Currently, only one additional element is generated. It is named caller_id and is of type RT_INTEGER. Example 5-2 and Example 5-3 show an info structure declaration (in C) with and without the -epi option. Equivalent structures are declared when generating Ada code.
Chapter 5 Generated Code Architecture Table 5-3. Procedure Ordering Task/Procedure Unique Identifier subsystem task 1 1 subsystem task 2 2 subsystem task 3 3 startup procedure 1 –4 startup procedure 2 –5 startup procedure 3 –6 background procedure 1 7 background procedure 2 8 interrupt procedure 1 9 Notice the relative numbering within a task/procedure type. Also, be aware that standard procedures are not given a unique identifier for the purposes of the caller_id element.
Chapter 5 Generated Code Architecture however, is to create additional space when declaring a variable of the info structure’s type and for the new code generated with the -epi option, which assumes the field exists in all procedure info structures. However, the old procedure cannot call a procedure generated with the extended field in the info structure.
Chapter 5 Generated Code Architecture Asynchronous Procedures Asynchronous Procedures are procedures that are not regularly scheduled to be executed or directly called from a subsystem or Standard Procedure. In other words, these procedures require some entity outside of the scope of the SystemBuild diagram to invoke them. The following rules apply to asynchronous procedures, but not necessarily to asynchronous subsystems. For details about asynchronous subsystems, refer to the AutoCode User Guide.
Chapter 5 Generated Code Architecture Changing %var Values During Startup A special feature of the Startup allows the value of a %var to be set at run-time through a Global Variable Block that has the same name as the %var. Condition Block SystemBuild provides three variations of the Condition Block: Default, No-Default, and Sequential. AutoCode only supports Standard and Macro Procedures within a Condition Block. AutoCode does not support inline procedures within a Condition Block.
Chapter 5 Generated Code Architecture The BlockScript block allows you to specify conditions and actions, define block inputs, outputs, and parameters, and specify their data types and dimensions. BlockScript then writes the update equations that process the inputs and parameters to produce the outputs. BlockScript I/O can be read by the Data Dictionary.
Chapter 5 Generated Code Architecture In Example 5-5, alpha, beta, and gamma are the variables to be used as representations for the inputs. Alpha is a scalar representing the input from pin 1. Beta is an array of integers representing inputs pins 2 through 6. Gamma follows as an array of floats representing pins 7 through 10. The result is just an array of integers representing all of the outputs pins.
Chapter 5 Generated Code Architecture Init, Output, and State Phases A subsystem has phases because the blocks within the subsystem need phases of computation. The three phases are intended to be used in a consistent way, just like the standard blocks. There are environment variables that indicate if a particular phase is active. Therefore, the canonical usage is that the appropriate environment variable is used as the guard in an IF statement.
Chapter 5 Generated Code Architecture Default Phase If you do not specify a phase and/or all code is not contained within an IF statement guarded by a phase environment variable, that code is generated in the Output phase and, if there is a State phase, that code also is generated in the State phase. Example 5-6 shows the phases.
Chapter 5 Generated Code Architecture Local Variables and Phases A local variable cannot be used to pass data between phases, because the different phases occur at different locations in the execution order of the whole subsystem or procedure. That is, local variables can be reused for other BlockScript block. Only inputs, outputs, parameters, and states are guaranteed to be correct between phases.
Chapter 5 Generated Code Architecture new_total = y; endif; Example 5-8 Generated Code from Example 5-7 void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { /***** States Array. *****/ static struct _Subsys_1_states ss_1_states[2] = {{0.0}, {0.0}}; /***** static static static Current and Next States struct _Subsys_1_states struct _Subsys_1_states struct _Subsys_1_states /***** Output Update. *****/ /* ---------------------------/* {bsb..2} */ if (INIT) { X->bsb_2_S1 = 0.0; } Pointers.
Chapter 5 Generated Code Architecture Continuous Semantics The state data within a continuous subsystem are called States and State Derivatives. These look very similar to the discrete equivalents, except that State data is integrated by the integrator algorithm. This is what is intended by using states within the continuous system. Therefore, if you just translated the previous discrete BlockScript block example into using States and State Derivatives, the results would be quite different.
Chapter 5 Generated Code Architecture In Example 5-9, a hard-subscript, i, is used to access both inputs and outputs. The reason i is a hard-subscript is that the range of i—that is, the values of 1 through to the number of inputs (u.size)—is known when the code is generated. AutoCode then can unroll the loop so as to translate y(i) into a single scalar variable for each value of i. The same is true for u(i). Example 5-9 Hard-Subscript Used to Access an Array Inputs: u; Outputs: y; float u(:), y(u.
Chapter 5 Example 5-11 Generated Code Architecture Local Variables Used to Allow Loops in Scalar Code Generation Inputs: u; Outputs: y; float u(:), y(u.size), local_u(u.size), local_y(y.size); integer i,j; for i = 1:u.size do local_u(i) = u(i); endfor; for i = 1:u.size do for j = i:u.size do local_y(i) = local_u(i) + local_u(j); endfor; endfor; for i = 1:y.
Chapter 5 Generated Code Architecture • FOR Loop—Can generate either a rolled or unrolled loop depending upon the range of the loop subscript and whether or not scalar code is generated. Table 5-4. Scalar Code Semantics for the Loop Types Loop Type Soft-Subscript Rolled Loop WHILE Not for inputs, outputs, or states Always FOR Not for inputs, outputs, or states No, unless the bounds of the loop are known and only local variables are used in the loop body Table 5-5.
Chapter 5 Generated Code Architecture Parameters Parameters represent data that can be used to provide data to tune the algorithm by representing coefficients in equations or persistent data somewhat like states. Parameters are implemented as persistent data when generated into code. Parameters can be initialized with hard-coded values or initialized using a %var as specified from the block dialog within the SuperBlock Editor. Parameters are designed for read-only data.
Chapter 5 Generated Code Architecture Example 5-14 BlockScript Block Example with Updating of a Parameter Inputs: u; Outputs: y; Environment: (OUTPUT, INIT); Parameters: total; float u,y,total; if OUTPUT then if !INIT then total = total + u; else total = u; endif; y = total; endif; Notice that you also must prevent an update during the Init phase, which requires the use of the nested IF statement.
Chapter 5 Generated Code Architecture else { total = U->bsb_1; } Y->bsb_22_1 = total; INIT = 0; Optimizations When translating a BlockScript block into source code, certain optimizations are automatically done. These optimization can reduce direct traceability from the script to the code at the expense of tighter code. Constant Propagation/Hard-Coding A local variable that is assigned a constant value is replaced with its value when code generates.
Chapter 5 Generated Code Architecture for i = 1:y.size do y(i) = 0.0; endif; endif; Example 5-17 Generated Code for BlockScript Block Example 5-16 /***** Output Update. *****/ /* ---------------------------- BlockScript Block */ /* {deadbsb..2} */ for (i=1; i<=5; i++) { deadbsb[-1+i] = U->deadbsb[-1+i]/0.001; } Notice that in the generated code, only the true-branch of the BlockScript if statement is generated, and that the local variable threshold was hard-coded.
Chapter 5 Generated Code Architecture UserCode Block The purpose of the UserCode Block (UCB) is to interface your existing code with AutoCode-generated source code. A UCB is typically used to access low-level device drivers or any algorithm not easily modeled within the diagram. Unfortunately, there are various types of UCBs with slightly different interfaces.
Chapter 5 Generated Code Architecture Parameterized UCB Callout A UCB can be defined with %var parameterized data for the UCB’s real parameters (RP) and integer parameters (IP). When used, AutoCode generates code that passes the %var variable as the actual of the UCB callout. A new option, -ucbparams, creates a temporary array within the subsystem code and passes the temporary arrays as actuals of the UCB callout.
Chapter 5 Generated Code Architecture Software Constructs These blocks provide the software constructs that are typically found in any imperative programming language such as C, Pascal, and FORTRAN.
Chapter 5 Generated Code Architecture BREAK Block The WHILE construct indefinitely iterates unless a BREAK Block is executed within the loop. You are responsible for properly detecting an exit condition and using it as an input to a BREAK Block inside the loop. If the input to the BREAK Block is TRUE, then the loop that is immediately enclosing the BREAK Block is exited. This block is implemented as a break statement in C and as an exit statement in Ada.
Chapter 5 Generated Code Architecture The Read from Variable Block optimization also is supported for Local Variable Blocks. Refer to Chapter 7, Code Optimization, for more details on optimization. Also, the sequencing of local variable blocks is similar to that of global variable blocks explained in the Global Variable Blocks section. Sequencer Block These blocks are used in the model to control the execution order of blocks.
Chapter 5 Generated Code Architecture representative of a sequence of equations. These equations are sensitive (that is, potentially numerically unstable) to the integration algorithm and order in which the equations are computed. Introducing multiple continuous subsystems or procedures introduces arbitrary boundaries within the equation sorting that can affect the stability of the total system.
Chapter 5 Generated Code Architecture • Algebraic loops are not supported. • AutoCode only performs a single initialization pass at time = 0.0. This corresponds to the SystemBuild Simulation options of INITMODE=0 or ACTIMING. Multiprocessor Code Generation Generation for a multiprocessor target is supported by AutoCode by heavily relying on a specialized template to generate a framework for the target.
Chapter 5 Generated Code Architecture Distributed Memory Architecture AutoCode also supports a multiprocessor architecture that uses distributed memory instead of shared memory. AutoCode does this by generating callouts (that is, macros) instead of the explicit code, and passes all of the necessary data to the callout. Unfortunately, there are potentially a large number of callouts to support various combinations of functionality and data type of the arguments.
Chapter 5 3. Generated Code Architecture Copy a block of local data into shared data: UPDATE_MBUF_WITH_LOCBLK(dest,src,size) 4. Copy shared data into local data: GET_LOCF_FROM_MBUFF(dest,src) GET_LOCB_FROM_MBUFB(dest,src) GET_LOCI_FROM_MBUFI(dest,src) GET_LOCF_FROM_MBUFI(dest,src) Mapping Command Options There is a set of command options that provide a way to direct AutoCode to generate code for specific functions on a specific processor.
Chapter 5 Generated Code Architecture • SLONG stands for signed long. • ULONG stands for unsigned long. The naming convention of the callouts uses the terms listed above and associates from right to left. The following is an example of a callout. UPDATE_MBUFSBYTE_WITH_LOCSBYTE(x, y) The value of the local variable x of type signed byte is assigned to a shared memory variable y of type signed byte. All of these callouts assume that the data type of x and y are identical except when noted.
Chapter 5 Generated Code Architecture UPDATE_MBUFF_WITH_MBUFUSHORT(x, y, convert_macro_name) UPDATE_MBUFSLONG_WITH_MBUFF(x, y, convert_macro_name) UPDATE_MBUFF_WITH_MBUFSLONG(x, y, convert_macro_name) UPDATE_MBUFULONG_WITH_MBUFF(x, y, convert_macro_name) UPDATE_MBUFF_WITH_MBUFULONG(x, y, convert_macro_name) The third argument, convert_macro_name, is the name of the fixed-point conversion macro that is used for conversion between fixed-point and floating-point numbers.
Chapter 5 Generated Code Architecture Example 5-21 shows template code to generate the required structure and pointer. All of the necessary information about the shared variable blocks is accessible from within the template using parameter information.
Chapter 5 Generated Code Architecture /**** declare pointer to shared variables ****/ volatile struct _shared_varblk *isi_varblk[1] = {&shared_var_blks}; @ENDIFF@ Example 5-21 assumes the existence of a fictional shared memory target such that the compiler supports #pragmas to declare the shared memory region. Your compiler and architecture will most likely have a different mechanism. The following list shows the requirements for shared variable block support.
Chapter 5 Generated Code Architecture Shared Memory Callout Option AutoCode supports a shared memory callout for all access to elements in shared memory. Callouts are generated when the -smco option is specified. The previous discussion about shared variable blocks still applies. However, the generated code is different, and you must supply the definitions of the callouts. Read Shared Variable Block Callouts There are currently four callouts used when reading from a shared variable block.
Chapter 5 Generated Code Architecture proc2_4_2 = Read_Shared_Varblk_Float(&isi_varblk[0]->block5[1]); Leave_Shared_Varblk_Section(4); /* ------------------------------- Write to Variable */ Enter_Shared_Varblk_Section(4); Write_Shared_Varblk_Float(&isi_varblk[0]->block5[0], proc2_4_1); Write_Shared_Varblk_Float(&isi_varblk[0]->block5[1], proc2_4_2); Leave_Shared_Varblk_Section(4); Global Variable Block Callouts Callouts are generated around each variable block access when the -vbco option is specified.
Chapter 5 Generated Code Architecture The formal argument represents the global reference number for which the variable block is being accessed. The default implementation of those simply calls the Disable( ) function.
Chapter 5 Generated Code Architecture The formal argument represents the global reference number for which the variable block is being accessed. The second formal argument, caller_id, represents a unique identifier for the caller. The default implementation of those simply calls the Enable( ) function. The following code uses the Enter_Local_Varblk... syntax to call non-shared global variable block generated code with callouts, using the -vbco and -epi options.
Chapter 5 Generated Code Architecture The first formal argument represents which processor the access is taking place on. Processor numbers are 1-based. The second formal argument represents the global reference number for which the variable block is being accessed. The following code uses the Enter_Shared_Varblk... syntax to call shared variable block generated code with callouts, using the -vbco option.
Chapter 5 Generated Code Architecture The following code uses the Enter_Shared_Varblk... syntax for shared variable block generated code with callouts, using the -vbco and -epi options.
6 Vectorized Code Generation This chapter discusses various ways to generate vectorized code. This includes describing the options available, design guidelines, and implementation details about the vectorized code. Introduction AutoCode has the capability to generate vectorized code. The default code generation style, however, remains to be all scalars.
Chapter 6 Vectorized Code Generation Scalar Gain Block Example Example 6-1 shows the scalar code generated for a gain block. Example 6-1 Scalar Code Generated for Gain Block Example void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { static RT_INTEGER iinfo[4]; /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update.
Chapter 6 Vectorized Code Generation where Y(i) is the ith output U(i) is the ith input GainParameter(i) is the ith gain value i is the range <1..x>, where x is the number of outputs of the block As you can see from the code generation, each of the ith elements of the gain block is represented by a uniquely named variable. Therefore, the basic equation is considered to be unrolled or code generated with scalars. The second characteristic is the gain parameters.
Chapter 6 Vectorized Code Generation if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; for( cnt=0;cnt<10;cnt++ ) { R_P[cnt] = _R_P[cnt]; } SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {gain..
Chapter 6 Vectorized Code Generation addition to issues with the standard block library, all general BlockScript Blocks within the diagram are implemented as 1-based arrays. If the subscript can be evaluated at generation-time, the 0-based subscript will be used. The extra computation of the subscripts represents a compatibility issue. Elimination of the 1-based array representation in BlockScript will be addressed in a future release.
Chapter 6 Vectorized Code Generation Figure 6-1. Poorly Connected Gain Block Example 6-3 Generated Code for Poorly Connected Gain Block (for Figure 6-1) void subsys_1(U, Y) struct _Subsys_1_in *U; struct _Subsys_1_out *Y; { static RT_INTEGER iinfo[4]; /***** Parameters. *****/ static RT_FLOAT R_P[5]; RT_INTEGER cnt; static const RT_FLOAT _R_P[5] = {1.2, 2.3, 3.4, 4.5, 5.6}; /***** Algorithmic Local Variables. *****/ RT_INTEGER i; /******* Initialization.
Chapter 6 Vectorized Code Generation /* ---------------------------- Gain Block */ /* {gain..2} */ Y->gain_2_1[0] = 1.2*U->gain_1[0]; Y->gain_2_1[1] = 2.3*U->gain_1[2]; Y->gain_2_1[2] = 3.4*U->gain_1[3]; Y->gain_2_1[3] = 4.5*U->gain_1[5]; Y->gain_2_1[4] = 5.6*U->gain_1[6]; This example shows that the penalty for poor connectivity can be great. In this case, the vectorized code is not an improvement over scalar code.
Chapter 6 Vectorized Code Generation Vector Labels and Names The SuperBlock Editor lets you give a name to a range of signals using a special notation. The Editor then repeatedly applies that name to the range. AutoCode interprets this type of labeling as a definition of which pins are to be an array. For more information about vector labeling, refer to the SystemBuild User Guide. The editor lets you use a vector label more liberally than what makes sense for code generation.
Chapter 6 Vectorized Code Generation Figure 6-2. Example Model Diagram Example 6-4 Maximal Vectorized Code Generation (for Figure 6-2) /******* System Ext I/O type declarations. *******/ struct _Subsys_1_out { RT_FLOAT delayed_pulse[5]; }; struct _Sys_ExtIn { RT_FLOAT sensor_5[5]; }; /***** States type declaration. *****/ struct _Subsys_1_states { RT_FLOAT sensor_delay[5]; }; void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { /***** States Array.
Chapter 6 Vectorized Code Generation static static static static static struct _Subsys_1_states *X; struct _Subsys_1_states *XD; struct _Subsys_1_states *XTMP; RT_INTEGER iinfo[4]; RT_INTEGER INIT; /***** Parameters. *****/ static RT_FLOAT R_P[11]; RT_INTEGER cnt; static const RT_FLOAT _R_P[11] = {0.1, 0.0, 0.0, 0.0, 0.0, 0.0, -8.7, -7.6, -6.5, -5.4, -4.3}; /***** Local Block Outputs. *****/ RT_FLOAT Throttle[5]; /***** Algorithmic Local Variables.
Chapter 6 Vectorized Code Generation } SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update. *****/ /* ---------------------------- Time Delay */ /* {VecEx..12} */ if (INIT) { k = 0; for (i=1; i<=5; i++) { X->sensor_delay[k] = R_P[i]; k = k + 1; } } k = 1; for (i=1; i<=5; i++) { Y->delayed_pulse[-1+i] = X->sensor_delay[-1+k]; k = k + 1; } /* ---------------------------- Gain Block */ /* {VecEx..2} */ for (i=1; i<=5; i++) { Throttle[-1+i] = R_P[5+i]*U->sensor_5[-1+i]; } /***** State Update.
Chapter 6 Vectorized Code Generation Example 6-5 Mixed Vectorized Code Generation (for Figure 6-2) /******* System Ext I/O type declarations. *******/ struct _Subsys_1_out { RT_FLOAT delayed_pulse[5]; }; struct _Sys_ExtIn { RT_FLOAT sensor_5; RT_FLOAT sensor_11; RT_FLOAT sensor_12; RT_FLOAT sensor_4; RT_FLOAT sensor_1; }; /***** States type declaration. *****/ struct _Subsys_1_states { RT_FLOAT sensor_delay[5]; }; void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { /***** States Array.
Chapter 6 Vectorized Code Generation RT_FLOAT Brake; RT_FLOAT Gear; RT_FLOAT Clutch; /***** Algorithmic Local Variables. *****/ RT_INTEGER i; RT_INTEGER j; RT_INTEGER k; /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; INIT = 1; X = &ss_1_states[0]; XD = &ss_1_states[1]; { RT_INTEGER ii; for( ii=0;ii<5;ii++ ) { X->sensor_delay[ii] = 0.0; } } { RT_INTEGER ii; for( ii=0;ii<5;ii++ ) { XD->sensor_delay[ii] = 0.
Chapter 6 Vectorized Code Generation k = k + 1; } } k = 1; for (i=1; i<=5; i++) { Y->delayed_pulse[-1+i] = X->sensor_delay[-1+k]; k = k + 1; } /* ---------------------------- Gain Block */ /* {VecEx..2} */ Throttle = -8.7*U->sensor_5; Pedal = -7.6*U->sensor_11; Brake = -6.5*U->sensor_12; Gear = -5.4*U->sensor_4; Clutch = -4.3*U->sensor_1; /***** State Update. *****/ /* ---------------------------/* {VecEx..
Chapter 6 Note Vectorized Code Generation The examples within this section assume maximal vectorization unless otherwise noted. Multiple Arrays within a Block All blocks support multiple vectors (arrays) as both outputs and inputs. However, depending on exactly how the signals are connected and the algorithm, loops might not be generated as expected. Generally speaking, as long as multiple arrays are connected contiguously to the inputs of the block, loops are possible.
Chapter 6 Vectorized Code Generation 1.2, 2.3, 3.4, 4.5, 5.6, 1.0, 1.0, 1.0, 1.0, 1.0}; /***** Local Block Outputs. *****/ RT_FLOAT top[5]; RT_FLOAT bottom[5]; /***** Algorithmic Local Variables. *****/ RT_INTEGER i; /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; for( cnt=0;cnt<20;cnt++ ) { R_P[cnt] = _R_P[cnt]; } SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {gain..
Chapter 6 Vectorized Code Generation The interesting part is that of the last gain block (gain..99). Notice that although two distinct arrays are used as input, because the input arrays are connected contiguously, the code is rolled into two separate loops. The generalized capability can be thought of as a replication of the block algorithm to produce the best vectorization based on the inputs, outputs, and the block algorithm.
Chapter 6 Vectorized Code Generation Figure 6-4. Example of a Split Vector Example 6-7 Generated Code for Split Vector (for Figure 6-4) /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {gain.top.2} */ for (i=1; i<=5; i++) { top[-1+i] = R_P[-1+i]*U->gain_1[-1+i]; } /* ---------------------------- Gain Block */ /* {gain.bottom.1} */ for (i=1; i<=5; i++) { bottom[-1+i] = R_P[4+i]*U->gain_1[4+i]; } /* ---------------------------- Gain Block */ /* {gain..
Chapter 6 Vectorized Code Generation The two producer gain blocks (top, bottom) vectorize as expected. The (gain..99) does not vectorize well. Notice that AutoCode was only able to vectorize two inputs while the remaining four were unrolled. AutoCode does not attempt to reconnect your diagram to generate better vectorized code.
Chapter 6 Vectorized Code Generation Example 6-8 Generated Code (for Figure 6-5) /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {gain.top.2} */ for (i=1; i<=5; i++) { top[-1+i] = R_P[-1+i]*U->gain_1[-1+i]; } /* ---------------------------- Gain Block */ /* {gain.bottom.1} */ for (i=1; i<=5; i++) { bottom[-1+i] = R_P[4+i]*U->gain_1[4+i]; } /* ---------------------------- Gain Block */ /* {gain.merge.
Chapter 6 Vectorized Code Generation You should notice two things in the code shown in Example 6-8. First, the gain block added to merge the data is generated as copies from the respective inputs into the single array. Second, the integrator block is tightly rolled. If the merge was not present, the Integrator would have been unrolled, causing a 6-fold increase in the amount of code for that block.
Chapter 6 Vectorized Code Generation Figure 6-6. Copy-Back Example Example 6-9 Generated Code (for Figure 6-6) void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { /**** some code deleted ****/ /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {gain.top.
Chapter 6 Vectorized Code Generation Eliminating Copy-Back There are many design ways to eliminate or hide the extra copies of the copy-back. All of them can be categorized into two groups: • Use Mixed Vectorization mode and force scalars to be used for the block is sparse external outputs. This eliminates rolling of the block algorithm while eliminating the copy. • Take all of the outputs of the block as external outputs.
Chapter 6 Vectorized Code Generation Figure 6-7. Vectorized Procedure Interface Example 6-10 Generated Code (for Figure 6-7) /******* Procedure: vecproc *******/ void vecproc(vecproc_1, vecproc_2_1, I) RT_FLOAT vecproc_1[5]; RT_FLOAT vecproc_2_1[5]; struct _vecproc_info *I; { /**** some code deleted ****/ /***** Output Update. *****/ /* ---------------------------- Gain Block */ /* {vecproc..
Chapter 6 Vectorized Code Generation top[-1+i] = R_P[-1+i]*U->gain_1[-1+i]; } /* ---------------------------- Procedure Super Block */ /* {vecproc.3} */ vecproc(&top[0], &Y->vecproc_3_1[0], &vecproc_3_i); iinfo[0] = vecproc_3_i.iinfo[0]; if( iinfo[0] != 0 ) { vecproc_3_i.iinfo[0] = 0; goto EXEC_ERROR; } A vectorized procedure interface suffers from a form of the copy-back problem. When using the vectorized interface, each time the procedure is called, the inputs and outputs must be an array.
Chapter 6 Vectorized Code Generation INIT := TRUE; X := ptr_of(ss_1_states(0)’address); XD := ptr_of(ss_1_states(1)’address); X.sensor_delay := (others => 0.0); XD.sensor_delay := (others => 0.0); for cnt in RT_INTEGER range 0..10 loop R_P(cnt) := RP(cnt); end loop; SUBSYS_PREINIT(1) := FALSE; return; end if; ------ Output Update. ------- ---------------------------- Time Delay --- {VecEx..12} -if INIT then k_1 := 0; for i_1 in RT_INTEGER range 1..5 loop X.
Chapter 6 Vectorized Code Generation ------ Swap state pointers. -----XTMP := X; X := XD; XD := XTMP; INIT := FALSE; end; Vectorization of the BlockScript Block The general BlockScript block is commonly used to implement very complicated or custom algorithms within a single block. A major limitation was the so-called soft-index limitation that occurred when generating code. The soft-index limitation existed because BlockScript represented inputs and outputs as vectors while AutoCode generated scalars.
Chapter 6 Vectorized Code Generation Matrix Outputs When you provide matricized output labeling for a block, AutoCode generates the resulting “matrix” as a single-dimensional array, even in Ada. This means that the output of a matrix-labeled block and the output of a vector-labeled block are identical, provided the number of elements in the matrix matches the number in the vector. This paradigm was selected because it insulates the “user” of a signal from the nature of the signal source.
7 Code Optimization This chapter explains the details of generating production quality code for micro controller-based applications. Generally, micro controller-based applications have stringent requirements for code size and execution speed. AutoCode supports various optimizations that could be used effectively to generate highly optimal code both in terms of speed and code size.
Chapter 7 Code Optimization static RT_INTEGER iinfo[4]; /***** Local Block Outputs. *****/ RT_FLOAT new_11_1; RT_FLOAT new_1_1; RT_FLOAT new_12_1; /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update. *****/ /* ---------------------------- Read from Variable */ /* {new..11} */ new_11_1 = var; /* ---------------------------- Read from Variable */ /* {new..
Chapter 7 Example 7-2 Code Optimization Code Generated with Variable Block Optimization Turned On /* Model variable definitions */ RT_FLOAT var; RT_FLOAT var1; void subsys_1(U, Y) struct _Sys_ExtIn *U; struct _Subsys_1_out *Y; { static RT_INTEGER iinfo[4]; /***** Local Block Outputs. *****/ RT_FLOAT new_11_1; RT_FLOAT new_12_1; /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update.
Chapter 7 Code Optimization iinfo[1] = 0; } return; EXEC_ERROR: ERROR_FLAG[1] = iinfo[0]; iinfo[0]=0;}} AutoCode performs this optimization only if it is safe to do so. There could be circumstances that could potentially prevent this optimization from taking place. AutoCode looks for the presence of a write-to-the-same-variable block between the Read from Variable block statement and its use in later computations.
Chapter 7 Code Optimization Write to the same variable block. Due to the cyclic nature of loops, any Write to Variable block inside the loop appears in between the Read from Variable block outside the loop and its use inside the loop. Restart Capability AutoCode generates code that supports application restart capability—that is, an application that is being run can be stopped and restarted again without having to download it again.
Chapter 7 Code Optimization static const RT_FLOAT _R_P[8] = {-1.0, 1.0, 1.5, 2.0, -1.0, 1.0, 1.25,1.4}; /***** Local Block Outputs. *****/ RT_FLOAT proc_2_1; RT_FLOAT proc_14_1; RT_FLOAT proc_12_1; /***** Algorithmic Local Variables. *****/ RT_INTEGER ilower; RT_INTEGER iupper; RT_FLOAT uval; RT_INTEGER k; RT_FLOAT alpha; /******* Initialization.
Chapter 7 Code Optimization the buffer _R_P and the initialization code are optimized away. Instead, the buffer R_P (parameter array), states, derivatives, and info structures are initialized directly in the declaration portion. After these structures are modified by computations, the initial values are lost, and the application cannot be restarted again.
Chapter 7 Code Optimization Merging INIT Sections Most of the dynamic blocks have explicit initialization, output update and state update sections. The initialization section is guarded by an INIT Boolean variable that is TRUE only for the first time a subsystem or a procedure is called. Each initialization section is tested every time the subsystem or procedure is executed. AutoCode supports an option where all such initialization branches can be merged into a single initialization branch.
Chapter 7 Code Optimization /* ---------------------------- Time Delay */ /* {proc..22} */ if (INIT) { X->proc_22_S1 = 0.0; } proc_22_1 = X->proc_22_S1; /* ---------------------------- Time Delay */ /* {proc..24} */ if (INIT) { X->proc_24_S1 = 0.0; } proc_24_1 = X->proc_24_S1; /* ---------------------------- Sum of Vectors */ /* {proc..14} */ proc_14_1 = U->proc_1 - proc_22_1; /* ---------------------------- Gain Block */ /* {proc..12} */ proc_12_1 = 2.
Chapter 7 Code Optimization X->proc_22_S1 = 0.0; X->proc_24_S1 = 0.0; XD->proc_22_S1 = 0.0; XD->proc_24_S1 = 0.0; /* ---------------------------/* {proc..22} */ X->proc_22_S1 = 0.0; /* ---------------------------/* {proc..24} */ X->proc_24_S1 = 0.0; SUBSYS_PREINIT[1] = FALSE; return; Time Delay */ Time Delay */ } /***** Output Update. *****/ /* ---------------------------- Time Delay */ /* {proc..22} */ proc_22_1 = X->proc_22_S1; /* ---------------------------- Time Delay */ /* {proc..
Chapter 7 Code Optimization In Example 7-5, both time delay blocks have separate INIT sections. In Example 7-6, the initialization code for these blocks is merged along with the subsystem initialization section. Reuse of Temporary Block Outputs Subsystems and procedures generated by AutoCode contain computations of individual blocks. Output of these blocks could be subsystem (procedure) outputs, or it could be temporary. Temporary block outputs are used immediately in the subsequent computations.
Chapter 7 Code Optimization Example 7-7 shows code generated without the reuse option, and Example 7-8 shows code generated from the same models with the maximal reuse option. Example 7-7 Code Fragment without Reuse Optimization /***** Local Block Outputs. *****/ RT_FLOAT model_2_1; RT_FLOAT model_3_1; RT_FLOAT model_4_1; /***** Output Update. *****/ /* ---------------------------/* {model..5} */ if (INIT) { X->model_5_S1 = 0.
Chapter 7 Code Optimization } Y->model_5_1 = X->model_5_S1; /* ---------------------------- Gain Block */ /* {model..2} */ model_2_1 = 2.0*U->model_1; /* ---------------------------- Sum of Vectors */ /* {model..3} */ model_3_1 = model_2_1 - U->model_1; /* ---------------------------- Gain Block */ /* {model..4} */ model_2_1 = 3.0*model_3_1; /***** State Update. *****/ /* ---------------------------/* {model..
Chapter 7 Code Optimization All of the blocks can accept constants as inputs. If any input is available during code generation time as a constant, the constant is used instead of a symbol name (or variable name). This applies to blocks of both categories. One limitation to this optimization is that a block cannot propagate constants or even accept constants as inputs if its inputs or outputs contain vectors.
Chapter 7 Code Optimization /* {const..4} */ Y->const_4_1 = 2.0*const_2_1; .. .. Example 7-10 Code Generated with the Constant Propagation Option void subsys_1(Y) struct _Subsys_1_out *Y; { static RT_INTEGER iinfo[4]; /***** Local Block Outputs. *****/ /******* Initialization. *******/ if (SUBSYS_PREINIT[1]) { iinfo[0] = 0; iinfo[1] = 1; iinfo[2] = 1; iinfo[3] = 1; SUBSYS_PREINIT[1] = FALSE; return; } /***** Output Update. *****/ /* ---------------------------/* {const..
Chapter 7 Code Optimization input of the gain block and the expression 2.0 * const_2 is evaluated to 4 as the value of const_2_1 is 2. Hence, the subsystem output gets the value 4. The command-line option for invoking this optimization is -Opc.
Chapter 7 Code Optimization constant block is optimized away, including the output variable. Also notice that the existing Constant Propagation optimization can be used with the constant block, but will only operate on scalar pieces of the constant block output. Optimizing with Callout Blocks The MatrixInverse, MatrixRightDivide, and MatrixLeftDivide blocks are implemented with callouts and therefore carry a special set of rules that must be followed to generate optimal code.
Chapter 7 Code Optimization If you have decided on the MatrixRightDivide block, the tips for optimizing the inputs are much the same as for the MatrixInverse block. In this case there are two inputs, A and B, and both are modified by the callout algorithm. Thus, a copy-in must occur for each input. Again, you cannot avoid the copy-in, but you can get tighter code with good input connectivity because the code will be looped rather than unrolled.
Chapter 7 Code Optimization Table 7-1.
8 AutoCode Sim Cdelay Scheduler This chapter discusses the Sim Cdelay low-latency scheduler. Introduction The default AutoCode scheduler is based on high throughput. Latency is acceptable as long as scheduler interrupt times are frequent. Because of this emphasis, each scheduler cycle is kept to an absolute minimum so that task queuing and output posting occurs only once per cycle. While providing high throughput and determinacy, this strategy has an impact on the latency of triggered and enabled tasks.
Chapter 8 AutoCode Sim Cdelay Scheduler real-time hardware. It assumes the reader is familiar with the concepts of AutoCode’s default scheduler. Refer to the AutoCode User Guide for more information about the scheduler, task types, and output posting. Task Posting Policies The task characteristics that have the most impact on scheduler design are task type, and output posting policy.
Chapter 8 AutoCode Sim Cdelay Scheduler Standard AutoCode Scheduler To illustrate the behavior of the standard AutoCode scheduler with triggered and enabled SuperBlocks, it is helpful to consider the diagnostic model shown in Figure 8-1, which features such SuperBlocks driven by a 5 Hz pulse train and fed a time signal as input.
Chapter 8 AutoCode Sim Cdelay Scheduler Figure 8-1. Model with Enabled and Triggered Tasks Under the default AutoCode scheduler, the output of this system is as shown in Figure 8-2. The top signal (corresponding to the triggered task) shows a latency of two cycles relative to its trigger input (immediately below), while the lower signal (corresponding to the enabled task) shows a latency of three cycles relative to its enable input. You will observe in the AutoCode Reference 8-4 ni.
Chapter 8 AutoCode Sim Cdelay Scheduler trig_sb_out 1.2 1 0.8 0.6 0.4 0.2 0 Trigger Signal 1 0.8 0.6 0.4 0.2 0 enab_sb_out 1.2 1 0.8 0.6 0.4 0.2 0 enab_signal Scheduler Pipeline section that these latencies are caused by the single posting stage per scheduler invocation in the default AutoCode scheduler, and by the output posting policy assigned to enabled blocks in the default scheduler. 1 0.8 0.6 0.4 0.2 0 0 0.5 1 1.5 Time Figure 8-2.
Chapter 8 AutoCode Sim Cdelay Scheduler triggers/enables have gone high are queued for execution. Then, in stage D, ATR tasks whose output posting times have arrived and ANC tasks that have just been queued for execution in stage C are marked for output posting, which is stage E.1, 2 Datastores are written from external inputs in stage F (overwriting any previous values for that cycle). Finally, in stage G, queued tasks are dispatched for execution.
Chapter 8 AutoCode Sim Cdelay Scheduler queue tasks stage for that scheduler invocation has already passed; thus, the triggered task cannot be queued for execution until 0.7 sec. At the time that it is queued, it sets its time delay for 0.1 sec. Thus, its output is not posted until the next scheduler invocation. In total, two scheduler ticks have thus passed before the triggered task’s outputs have been posted. The case of the enabled task is slightly more complicated.
Chapter 8 AutoCode Sim Cdelay Scheduler Now the inherent problem in the standard scheduler is clear. From launch to output posting, you suffer a two-cycle delay for triggered tasks, and a three-cycle delay for enabled tasks, instead of the standard unit cycle delay present on real-time hardware for free-running periodic tasks. Your goal will be to reduce both of these latencies to single-cycle delays. The scheduler pipeline stages in the Sim Cdelay AutoCode scheduler are shown in Figure 8-4.
Chapter 8 AutoCode Sim Cdelay Scheduler Sim Cdelay Scheduler As stated at the outset, the goal of this project was to develop a new AutoCode scheduler, runnable on real-time targets, which mimics the behavior of Sim with Cdelay (actiming off). Sim with Cdelay differs from Sim with actiming in several key ways, including scheduler pipeline, task output posting policies, enable policies, and retriggering behavior for triggered tasks.
Chapter 8 AutoCode Sim Cdelay Scheduler triggers arriving too quickly can prevent a task from ever posting any output. You must build an alternative AutoCode scheduler incorporating the new pipeline stages presented above, and change the transition diagrams of many of the task types to reflect changed output posting, enable, and retriggering policies.
Chapter 8 Timer greater than zero, decrement it Timer is zero and !enable, reset timer Timer is zero and !enable, reset timer and post outputs AutoCode Sim Cdelay Scheduler Timer is zero and enable, reset timer BLOCKED task done RUNNING IDLE Timer is zero and enable, reset timer and post outputs Timer greater than zero, decrement it Timer has reached zero, signal overflow Figure 8-6.
Chapter 8 AutoCode Sim Cdelay Scheduler These transition diagrams, together with the diagrams in Chapter 4, Managing and Scheduling Applications, of the AutoCode User Guide, define the behavior of tasks under the Sim with Cdelay scheduler. They encompass all of the changes to the default scheduler outside the scheduler pipeline, and embody the new output posting, enable, and retriggering policies.
Chapter 8 AutoCode Sim Cdelay Scheduler DataStore Priority Problem As mentioned, you must find some way to enforce the priority of writers to DataStores in the generated code. Each DataStore register can be written to independently, so each one needs to be independently subjected to the priority constraint. In the default scheduler, there is no need to actively enforce the constraint, as it is automatically preserved by the order in which outputs are posted in the single output stage.
Chapter 8 AutoCode Sim Cdelay Scheduler for tsk <- low_prio_tsk..high_prio_tsk do { /* loop from low to high priority */ if tsk.ready_to_post_outputs() if tsk.prio() > reg_prio /* higher priorities are larger */ write_register(tsk.output()); /*write to datastore register*/ In the generated code, the priorities of all DataStore registers in Alpha are stored in a single, file-scoped array called DSTORE_GUARD, which is optimized away if Alpha is empty.
trig_sb_out 1.4 1.2 1 0.8 0.6 0.4 0.2 0 Trigger Signal 1 0.8 0.6 0.4 0.2 0 enab_sb_out 1.4 1.2 1 0.8 0.6 0.4 0.2 0 enab_signal Chapter 8 1 0.8 0.6 0.4 0.2 0 0 0.5 1 AutoCode Sim Cdelay Scheduler 1.5 Time Figure 8-8.
Chapter 8 AutoCode Sim Cdelay Scheduler At the template level, the default Sim with Cdelay ATR triggered task behavior of re-queueing a task for execution on receipt of a new trigger before the outputs have been posted can be turned off by replacing the segment call Sim_style_ATR_Idle by a call to NoRetrigger_style_ATR_Idle.
Chapter 8 AutoCode Sim Cdelay Scheduler that repeated until no new tasks where queued for execution. Given such an implementation, the chained ANC problem would disappear. However, under such a design, scheduler execution time would be variable and data dependent—undesirable attributes in any hard real-time scheduler. Contrast this with the new scheduler, which catches the first element of an ANC chain but has a fixed-length pipeline.
Global Scope Signals and Parameterless Procedures 9 This chapter discusses global scope signals and parameterless procedures. Introduction The memory and performance requirements of real-time production code force the issue of global variables. AutoCode does not generally use global variables; rather, it creates and uses stack variables and explicit interfaces. Whereas that architecture is perfectly sound, it does cause overhead in a production system.
Chapter 9 Global Scope Signals and Parameterless Procedures These new features address the following two uses: • Data Monitoring/Injection—The safe access to local subsystem signals for the purpose of monitoring the signal’s value during the execution of the model. This is intended as a way to provide debugging/monitoring information. • Parameterless Procedure—The ability to use global variable(s) to represent a procedure’s inputs and/or outputs.
Chapter 9 Global Scope Signals and Parameterless Procedures memory address, and that string is accessible through template tokens during code generation. Be careful when selecting only a partial subset of block outputs as Global Scope when generating vectorized code. NI recommends that if you intend for some of the block’s output to be global, you make them all global so as to preserve loops within the generated code.
Chapter 9 Global Scope Signals and Parameterless Procedures Limitations This section identifies some of the limitations of scoped output. Unsupported Blocks The following list presents the blocks that do not support scoped outputs.
Chapter 9 Global Scope Signals and Parameterless Procedures Parameterless Procedure A parameterless (argument-less) procedure is a procedure that uses global variable(s) to pass input(s) into and/or output(s) out of the procedure. Each input and output can be individually selected to be global or not. A parameterless procedure is purely a performance optimization that requires you to make design changes in your model to get the correct code.
Chapter 9 Global Scope Signals and Parameterless Procedures NI suggests that you adopt a naming convention for all of your global variables used for parameterless procedure signals. For example, specify all of the names with a leading “g,” like gThrottleValue. Note Output Specification Procedure outputs are specified from the basic blocks that connect to the external signal pins. Therefore, you must specify the global output of a procedure at the basic block that is the source of the output signal.
Chapter 9 Global Scope Signals and Parameterless Procedures Condition Block Code Generation The Condition Block supports the use of parameterless procedures. In the nodefault and sequential modes, the Condition Block will not buffer the global outputs of the procedure into the R_P (real parameter) array. For information about Condition Blocks, refer to the Condition Block section of Chapter 5, Generated Code Architecture.
Chapter 9 Global Scope Signals and Parameterless Procedures You must write template code to customize the declarations of these variables, which includes usage of the Memory Address string because this is target/compiler specific information. Note Issues and Limitations This section identifies some other items that you should be aware of if you intend to use parameterless procedures. Note Parameterless procedures require the use of global variables.
Chapter 9 Global Scope Signals and Parameterless Procedures Connection to External Output If a signal that is used as input to a Global Scope procedure input or a Global Scope procedure output is connected to a external output pin, be aware that the external output pins will be updated at the end of that subsystem during the subsystem copy-back phase.
Chapter 9 Global Scope Signals and Parameterless Procedures Analyzer and AutoCode Warnings The Analyzer reports questionable connectivities or situations regarding usage of the Global Scope signals. Also, AutoCode might report additional warnings during code generation. Evaluate these warnings and verify that the generated code is what you expect. You might need to change your model to fix the situation.
Technical Support and Professional Services A Visit the following sections of the National Instruments Web site at ni.com for technical support and professional services: • Support—Online technical support resources at ni.
Index A critical section with epi option, 5-52 critical section without epi option, 5-51 non-shared variable blocks, 5-51 pairs, 5-51 parameterized UCB, 5-38 shared global variable blocks, 5-53 critical section with epi option, 5-54 critical section without epi option, 5-53 shared memory, 5-50 read, 5-50 write, 5-50 shared memory fixed-point callouts Ada, 5-47 C, 5-46 variable blocks, 5-19 requirements, 5-49 shared variable block support, 5-47 template code, 5-48 code generation scalar, 6-1 example code fo
Index top-level, 2-2, 3-3 utilities, 2-2, 3-3 -DMSWIN32, 2-2 documentation conventions used in the manual, iv NI resources, A-1 -DOSF1, 2-2 drivers (NI resources), A-1 -DSGI, 2-2 -DSOLARIS, 2-1, 2-2 compile_ada_sa.sh compilation script, 3-11 compile_c_sa.sh compilation script, 2-11 compiling, 2-1 condition block. See generated code architecture, condition code Condition SuperBlock, 9-7 conditions and actions, 5-23 configuration file. See RTOS, configuration file CONTINUE Block, 5-40 continuous subsystems.
Index sa_fxr.h, 2-32, 2-33 sa_fxscale.h, 2-32, 2-33 sa_fxsub_byte.c, 2-34 sa_fxsub_byte.c file, 2-32 sa_fxsub_long.c, 2-32, 2-34 sa_fxsub_short.c, 2-32, 2-34 sa_fxtemps.h, 2-32, 2-33 sa_intgr.h, 2-4 sa_io.a, 3-4 sa_math.a, 3-4 sa_math.h, 2-4 sa_math_.a, 3-4, 3-5 sa_sys.h, 2-3, 2-4 sa_time.a, 3-4 sa_time.h, 2-3, 2-4 sa_time_.a, 3-4, 3-5 sa_types.h, 2-4, 2-32, 2-33 sa_types_.a, 3-4, 3-5 sa_types_.ada, 3-5 sa_user.a, 3-5 sa_user.c, 2-11 sa_user.h, 2-3, 2-4 sa_user_.a, 3-4, 3-11 sa_utils.a, 3-4 sa_utils.
Index example without wordsize extension, 2-41 files in src directory, 2-31 fixed-point variables, 2-28 fixed-point, data types, 2-28 for multiprocessor, 5-45 function interface, 2-27 implementation of fixed-point arithmetic, 2-26 intermediate results, 2-45 macro interface, 2-27 matching sim results, 2-45 order dependency, 2-45 overflow protection, 2-31 relational macros, 2-44 required interface files, 2-27 shared memory callouts, 5-46 user types, 2-30 UTs, 2-30 wordsize extension, 2-40 selecting, 2-42 FLO
Index dead code elimination, 5-35 implicit type conversion, 5-36 special directives, 5-36 inputs, 5-23 local variables, 5-24 outputs, 5-23 parameters, 5-33 phases, 5-25, 5-26 example of, 5-26 purpose states continuous subsystem, 5-29 discrete subsystem, 5-26 BREAK Block, 5-40 caller_id, 5-18, 5-19 condition code default mode no default mode, 5-22 sequential mode, 5-22 CONTINUE Block, 5-40 epi option, 5-19 global storage, 5-3 use of %vars, 5-3 global variable blocks, 5-41 IfThenElse Block, 5-39 interface la
Index sa_types.h, 2-4 sa_user.h, 2-4 sa_utils.h, 2-4 help system, 1-3 help, technical support, A-1 high-level language, code, 1-2, 3-16 distributed memory architecture, 5-44 mapping command options, 5-45 shared memory architecture, 5-43 callouts, 5-44 optimization for read-from variable blocks, 5-4 Sequencer Block, 5-41 similarities to compiler, 5-1 single-rate system, 5-8 software constructs, 5-39 subsystems. See subsystems symbolic names default, 5-1 generation of by AutoCode, 5-2 UCB.
Index L output posting, 8-2 overflow error message, 2-8 local variable blocks, 5-40, 5-41 local variables, 5-27 P M parameterized UCB callouts, 5-38 parameterless procedures.
Index R interrupt procedure SuperBlock table, 4-5 processor IP name table, 4-7 processors table, 4-3 -rtos command option, 4-8 -rtosf command option, 4-8 scheduler priority table, 4-4 startup procedure SuperBlock table, 4-7 subsystem table, 4-4 table syntax, 4-2 using, 4-8 version table, 4-8 R_P, 5-9 UCB fixed call argument, Ada, 3-12 rapid prototyping, 1-2 real-time code generating, 3-16 real-time file, 3-16 related publications, 1-4 reusable procedures example, 2-22 generated subsystem function, 2-25 g
Index sa_user.c file, 2-11 sa_user.h file, 2-3, 2-4 sa_user_.a file, 3-4, 3-11 sa_utils.a file, 3-4 sa_utils.ada file, 3-6 sa_utils.c file, 2-3, 2-5, 2-6 sa_utils.h file, 2-3, 2-4 sa_utils_.a file, 3-4, 3-5 sa_utils_.
Index error handling, 5-11 handling duplicates, 5-10 iinfo array, 5-9 phase condition, 5-9 phases init, 5-10 output, 5-10 state, 5-10 procedural interface unrolled interface, 5-12 procedure data, 5-10 sample and hold, 5-8 single-rate system, 5-8 static (persistent) data, 5-9 initializing, 5-10 top-Level SuperBlock, 5-6 unrolled interface, 5-12 SuperBlocks procedure, 2-20 standard procedures, 5-11 error handling, 5-12 handling %vars, 5-12 iinfo array, 5-17 info structure, 5-11 input arguments, 5-15 input st
Index fatalerr, 3-6 implementation_initialize, 3-6, 3-8, 3-10 implementation_terminate, 3-6 rewriting, 3-6 signal_remote_dispatch, 3-7 target-specific, 3-6 utility routines (C), 2-5 background, 2-5, 2-6 disable, 2-5, 2-6 enable, 2-5, 2-6 error, 2-5, 2-7, 2-8 error detection and causes, 2-7 errors in the generated code, 2-8 external_input, 2-6, 2-10 external_output, 2-6, 2-10 fatalerr, 2-5, 2-7 implementation_initialize, 2-5, 2-9 implementation_terminate, 2-6, 2-9 rewriting, 2-5 Signal_Remote_Dispatch, 2-6
Index X Y X (UCB fixed call argument) Ada, 3-12 C, 2-13 XD (UCB fixed call argument) Ada, 3-12 C, 2-13 XINPUT array, 2-10 Xmath {matrixx,ascii}, 2-7 XOUTPUT array, 2-10 Y (UCB fixed call argument) Ada, 3-12 C, 2-13 AutoCode Reference I-12 ni.