DSP_Block_Standardisation - david-macmahon/wiki_convert_test GitHub Wiki

This page documents the attempt to create a standard to be followed when creating new DSP blocks to be incorporated into the existing libraries. Large amounts of in-depth information will also be useful to people new to the DSP library wanting to add or edit blocks. Please see CASPER Simulink Style Guide

General

  • Aim: The aim of adding a block should be to remove the need for others to redo work already done by you. Adequate documentation, neat scripts and adherence to suggestions in this standard should prevent others doing more work than it would take to do it themselves. Please keep this in mind.
  • Location: All DSP blocks are currently located in the Simulink library CASPER DSP Blockset. All the blocks are located in casper_library.mdl in the casper_library directory in the subversion repository. All related scripts are located in casper_library too. Testbenches are located in the Tests subdirectory. If possible, new blocks should be added to this structure. Documentation for the libraries are located in the doc directory available at the same level as casper_library.
  • Scripts: All blocks should either be static or entirely created using a script. A mixture of static and dynamic creation is difficult to debug or modify. Purely static blocks should not be coloured and dynamic blocks coloured the same for the respective library.
  • Documentation: Each top-level block should have an appropriate entry made in the documentation infrastructure (in doc directory at same level as casper_library.
  • Testbenches: Each new top-level block added should have an associated testbench (Tests subdirectory in casper_libary).
  • Mixing Libraries: New library blocks should only contain blocks from the same library version (7.1, 10.1). Mixing in library blocks from different library versions can be dangerous as infrastructure scripts change between versions and may be incompatible.

Scripting

  • Use: Blocks requiring a dynamic internal structure (components or connections) should be constructed using a script. If a script is used to instantiate blocks, all blocks should be instantiated by the script. Partial static blocks are difficult to debug and modify.
  • File and function names: The initialisation function for each block should be contained in a separate file. The file name should be <block_name>_init.m (where <block_name> is the name of the block). The initialisation function should be <block_name>_init (again, where <block_name> is the name of the block).
  • Parameters: Mask parameters should be passed to the initialisation function in ('parameter_name', parameter_value) pairs where 'parameter_name' is a text string containing the name of the mask parameter and parameter_value is the associated value. An existing initialisation script will illustrate this technique.
  • Basic script structure: All scripts should contain the following basic structure.
  1. Comment block describing the purpose of the function and how it is to be used. Return values, as well as the type of expected parameters should be indicated. This should be placed first in the file to ensure a call to 'help <block_name)_init' returns something useful.
  2. A call to the same_state function. This function compares the mask parameters passed to the function to a hash generated the previous time an update was made. If parameter values have changed the rest of the initialisation script will be executed otherwise the rest of the script will not be run. Simulink calls the initialisation script of any block multiple times. It also calls scripts for all associated sub-blocks. This may cause a large amount of redundant, unnecessary script execution. The call to same_state helps check if the script requires execution or not.
  3. A call to check_mask_type. This is a sanity check and is used to check that the initialisation script is being called to operate on the appropriate block. This name can be set under the Documentation tab in the Mask Editor for a block.
  4. Invocation of munge_block function causes link to the original library block to be disabled if the block is not being instantiated in a library. This causes changes to local and not to propagate to the library. munge_block also may be used to prevent future modification of block mask parameters by passing 'munge' as a parameter (use help munge_block for more information).
  5. Use get_var to extract the various parameter values passed to the function.
  6. delete_lines removes all connections in the existing system. If any blocks remain unconnected at the end of the script, the call to clean_blocks removes them. This allows the easy removal of unneeded blocks while still allowing for the reuse of useful ones.
  7. At this point the script may create the needed system. Blocks should be instantiated using the reuse_block function. This searches for an existing block of the same type and sets the necessary parameters. If one is not available, a new one is created. Reuse is more efficient than creating all blocks from scratch each time.
  8. A call to clean blocks after all blocks are instantiated and connected ensures unconnected blocks are removed.
  9. Each Simulink block has a parameter called 'UserData' for storage of data by the useful. The call to save_state causes a data structure to be saved to this parameter. This structure consists of two fields; state contains a hash of the input arguments (used by same_state to determine if these have changed), and parameters contains a data structure with all the mask parameters passed to the initialisation function. save_state also updates the mask parameters and overwrites variable references with actual values. This forces mask values to change to values passed into the script. If mask values do not change, Simulink does not execute the initialisation script so this also forces a change in mask values as variables are expanded so that future change in these variables cause execution of the initialisation script.

Testbenches

  • A separate testbench should be created to test every path through a script that results in a viable system. This means that the testbench should not need to test for errors but, given valid parameters, should test that the correct system is generated. This does not imply a testing of all possible parameter combinations e.g all possible number of input ports. The testbenches should generate all possible internal structure including different blocks and the way in which blocks are connected.
  • Before checking your addition into the revision control system, ensure that the test infrastructure can run all tests without errors, i.e ensure that you your changes have not broken anything.
⚠️ **GitHub.com Fallback** ⚠️