Guide to using Dynamic Width Integers in XJEase
XJEase supports dynamic-width integers, in contrast to conventional programming languages such as C++ and hardware description languages like Verilog or VHDL. Common uses for this powerful feature are manipulating, extracting and aligning data and address bit fields. This sort of operation is very useful when writing tests for Flash Memory, DDR RAM or other device types.
XJEase dynamic-width integers can be up to 2^32 (over four billion) bits wide. Processing such large integers can reduce speed considerably so you need to take a little care with their use. This article describes how best to use dynamic-width integers.
Integers in XJEase can be declared to be of any width up to 2^32 bits. Integers default to a single bit if the width is not explicitly declared. In XJEase, integers can only increase in width and will never shrink, unless explicitly coded using the bit-slice operator. This way JTAG test data or other variables data cannot be accidentally lost in XJEase operations.
Integers will always grow to fit the size of the result of an operation; thus shifting an integer left by one will always cause it to increase its width by one bit (leading zeros are not truncated), and multiplying an integer will increase the width to a value sufficient to hold the result. This should be borne in mind when manipulating integers. Resizing of variables requires both processor time and additional memory so can reduce code performance and ultimately reduce the speed of boundary scan testing.
As an example of how you could easily affect JTAG test speed, the following code will cause the variable shift_reg to increase in size by one bit each time the loop executes. The left shift operation will require an additional bit to store the result causing a gradually increasing use of resources.
Deserialiser () (INT output) INT shift_reg WIDTH 8; INT i; INT bit WIDTH 1; FOR i := 1 FOR 8 SET bit := INPUT_PIN; shift_reg := (shift_reg << 1) | bit; END; output := shift_reg[7..0]; END;
This behaviour can have a significant effect on the performance of XJEase code, but you could avoid the problem by modifying the code as shown below:
Deserialiser () (INT output) INT shift_reg WIDTH 8; INT i; INT bit WIDTH 1; FOR i := 1 FOR 8 SET bit := INPUT_PIN; shift_reg := shift_reg[6..0] : bit; END; output := shift_reg; END;
Here the bit-slice and concatenation operators ([6..0] and : respectively) have been used to ensure that the variable shift_reg never grows to more than eight bits wide. This saves the processing time taken to resize the shift_reg variable on each iteration of the loop.
Another pitfall for the unwary arising from the use of dynamic-width integers is using the WIDTHOF expression on a dynamic-width variable. For example, the following code will generate an infinite loop, as the WIDTHOF operator will return ever-increasing values with iterations of the loop.
Deserialiser () (INT output) INT shift_reg WIDTH 8; INT i; INT bit WIDTH 1; FOR i := 1 FOR WIDTHOF(shift_reg) SET bit := INPUT_PIN; shift_reg := (shift_reg << 1) | bit; END; output := shift_reg; END;
Remember that XJEase variables will automatically grow in width if required to accommodate the result of any operation. When unnoticed this behaviour can consume significant processor resources and could slow down your code execution and JTAG testing. You can usually avoid the problem with careful coding techniques.