Program Image Generator (PIG) generates the bit image which can be uploaded to the target machine's memory for execution. Compression can be applied to the instruction memory image by means of instruction compression algorithm plugins.
Input: TPEF, BEM, ADF
Output: program bit image in alternative formats
The usage of the generatebits application is as follows:
generatebits <options> ADF
The possible options of the application are as follows:
|Short Name||Long Name||Description|
|b||bem||The binary encoding map file.|
|c||compressor||Name of the code compressor plugin file.|
|u||compressorparam||Parameter to the code compressor in form 'name=value'.|
|d||dataimages||Creates data images.|
|g||decompressor||Generates a decompressor block.|
|o||diformat||The output format of data image(s) ('ascii', 'array', 'mif' or 'binary'). Default is 'ascii'.|
|w||dmemwidthinmaus||Width of data memory in MAUs. Default is 1.|
|x||hdl-dir||Directory root where are the ProGe generated HDL files generated by ProGe. If given, PIG will write imem_mau_pkg and compressor in that directory. Otherwise they are written to cwd.|
|f||piformat||Determines the output format of the program image and data images. Value may be 'ascii', 'binary' or 'mif'.|
|s||showcompressors||Shows the compressor plugin descriptions.|
|p||program||The TPEF program file(s).|
|v||verbose||Display extra information during image creation: total immediates, different immediate values, instr. addresses, data addresses, full instruction NOPs and consecutive full instr. NOP groups.|
The application prints the program image to the standard output stream. It can be easily forwarded to a file, if wanted. The data images are generated to separate files, one for each address space. Names of the files are determined by the name of the address space and the suffix is .img. The files are generated to the directory in which the application is executed.
The binary encoding map input parameter may be omitted. If so, the BEM to be used is generated automatically. The BEM is used in the intermediate format of the program image, before it is compressed by the code compressor plugin. However, if no code compression is applied, the program image output matches the format defined in the BEM.
The options can be given either using the short name or long name. If short name is used, a hyphen (-) prefix must be used. For example -a followed by the name of the ADF file. If the long name is used, a double hyphen (- -) prefix must be used, respectively.
The following example generates a program image and data images of the address spaces in ASCII format without code compression.
generatebits -b encodings.bem -p program.tpef -f ascii -d machine.adf
TCE toolset includes two different code compressors: InstructionDictionary compressor and MoveSlotDictionary compressor. It is also possible to create new code compressors.
How these compressors work is that they analyze program's instruction memory and create a compressed instruction memory image. In order to use the compressed image the compressor also creates a decompressor module which replaces the default decompressor in the instruction decoder unit of a processor.
You can list the available compressor and their descriptions with
generatebits -s processor.adf
Instruction dictionary compressor analyzes a program and creates a look up table of all the unique instructions. Compressed instruction image then consists of indices to the created look up table. Decompressor module includes the look up table and it outputs the uncompressed instruction defined by the input index.
Here is an example how to use the instruction dictionary compressor:
generatebits -c InstructionDictionary.so -g -p program.tpef processor.adf
Command creates the compressed instruction memory image program.img and imem_mau_pkg.vhdl using InstructionDictionary.so plugin defined with the -c parameter. As the command also has -g parameter compressor creates the decompressor.vhdl file which defines the decompressor unit.
You can also give the existing proge-output directory (in this case processor_files) to generatebits:
generatebits -c InstructionDictionary.so -g -p program.tpef -x processor_files processor.adf
Now PIG will automatically write the imem_mau_pkg.vhdl and decompressor.vhdl to the right places in processor_files directory.
Move slot dictionary compressor analyzes the program and creates a separate look up table for each of the move slots in the processor. Every move slot in the compressed instruction then has an index to its look up table. As with the instruction dictionary compressor the decompressor module holds the look up tables and it decompresses the instruction on move slot basis.
Here is an example how to use the move slot dictionary compressor:
generatebits -c MoveSlotDictionary.so -g -p program.tpef processor.adf
Like earlier you can also use the proge-output folder parameter:
generatebits -c MoveSlotDictionary.so -g -p program.tpef -x processor_file processor.adf
By default, PIG does not apply any code compression to the program image. However, user can create a dynamic code compressor module which is loaded and used by PIG. To define a code compressor, a C++ class derived from CodeCompressorPlugin class must be created and compiled to a shared object file. The class is exported as a plugin using a macro defined in CodeCompressor.hh file. The buildcompressor script can be used to compile the plugin module.
As mentioned, the code compressor class must be derived from CodeCompressorPlugin base class. The code compressor class must implement the virtual compress() method of the CodeCompressorPlugin class. An example of a simple dictionary compressor is defined in compressors/simple_dictionary.cc file in the source code distribution.
The compress method is the heart of the compressor. The compressor method returns the complete program image as a bit vector. The task of the method is to call the addInstruction method of the base class sequentially to add the instructions to the program image. The base class does the rest of the job. You just have to provide the bits of each instruction in the parameter of addInstruction calls. Finally, when all the instructions are added, the program image can be returned by calling the programBits method of the base class.
The instruction bits are provided as InstructionBitVector instances. That class provides capability to mark which bits of the instruction refer to address of another instruction and thus are likely to be changed when the real address of the referred instruction is known. It is the responsibility of code compressor to mark that kind of bits to the instruction bit vectors given in addInstruction calls. The base class will change the bits when the referred instruction is added (when its address is known).
The code compressor should tell the base class which instructions must be placed in the beginning of a MAU block. For example, the jump targets should be in the beginning of MAU. Otherwise instruction fetching will get difficult. This can be done by calling the setInstructionToStartAtBeginningOfMAU method of the base class. If all the instructions are meant to start at the beginning of MAU, setAllInstructionsToStartAtBeginningOfMAU method is handy. By default, all the instructions are concatenated without any pad bits in between them, whatever the MAU of the instruction memory is. Note that setInstructionToStartAtBeginningOfMAU / setAllInstructionsToStartAtBeginningOfMAU method(s) must be called before starting to add instructions with addInstruction method.
The CodeCompressorPlugin base class provides some handy methods that might be useful for the code compressor implementation. The following lists the most important ones:
When the code compressor module is coded, it must be compiled to a shared object. It can be done with the buildcompressor script. The script takes the name of the object file to be created and the source file(s) as command line parameters. The output of the script, assuming that everything goes fine, is the dynamic module that can be given to the generatebits application.
Pekka Jääskeläinen 2018-03-12