Engee documentation
Notebook

Extracting individual bits from a number

In this demo, we'll show you how to work with the block. Extract Bits, which allows you to extract the bits located at the specified positions of the input number.

This block is very useful in designing algorithms for digital communication systems, in modeling bit signal lines in control systems or robotics, as well as in various graphical programming tasks.

Description of the model

Block Extract Bits accepts an integer as input and generates a new number from it at the output. In the block properties, you can specify which bits from the input number will be copied and which will not.

Launching the model

In the example, we will feed the block input Extract Bits a constant of the type UInt8 with a value of 255. All the bit positions of this eight-bit number are occupied by units. Let's show two modes of operation of the block. Extract Bits:

  • Preserve fixed-point scaling — The fixed-point scaling of the input data is used to determine the scaling of the output during data type conversion.
  • Treat bit field as an integer — the scaling of the input data with a fixed point is ignored, and only the stored integer is used to calculate the type of output data.

Now we will see how the work of both methods differs.

Treat bit field as an integer

Model extract_bits_treat_bit_fields_as_integer demonstrates the operation of the mode in which the extracted sequence of bits becomes the low-order bits in the output signal of the block.

The signal MSB, obtained from the number 255 by taking the two highest bits of the number, will be equal to 0b11 (number 3), because the sequence of bits is 11 it is shifted to the place of the low-order bits.

image.png

Preserve fixed-point scaling

Model extract_bits_preserve_fixed_point_scaling demonstrates a different block operation mode. In this mode, the sequence of selected bits remains in its place in the bit grid of the number, the remaining positions are replaced by zeros. We can say that in this way the block implements masking of bits in the number.

The MSB signal will now be equal to 0b11000000 that is 192.

image.png

Model Comparison

Let's run both models by means of software control of modeling:

In [ ]:
modelName = "extract_bits_preserve_fixed_point_scaling"
model = modelName in [m.name for m in engee.get_all_models()] ? engee.open( modelName ) : engee.load( "$(@__DIR__)/$(modelName).engee");
data1 = engee.run( modelName );

modelName = "extract_bits_treat_bit_fields_as_integer"
model = modelName in [m.name for m in engee.get_all_models()] ? engee.open( modelName ) : engee.load( "$(@__DIR__)/$(modelName).engee");
data2 = engee.run( modelName );
In [ ]:
plot(
    scatter( collect(1:8), replace( data1["Input"].value[end], 0=>NaN), ylims=(0,2), title="Preserve fixed point scaling\n(маскирование)", ylabel="Input", titlefont=font(9) ),
    scatter( collect(1:8), replace( data2["Input"].value[end], 0=>NaN), ylims=(0,2), title="Treat bit fields as integer\n(выборка)", titlefont=font(9) ),
    scatter( collect(1:8), replace( data1["MSB"].value[end], 0=>NaN), ylims=(0,2), ylabel="MSB" ),
    scatter( collect(1:8), replace( data2["MSB"].value[end], 0=>NaN), ylims=(0,2) ),
    scatter( collect(1:8), replace( data1["Mid SB"].value[end], 0=>NaN), ylims=(0,2), ylabel="Mid SB" ),
    scatter( collect(1:8), replace( data2["Mid SB"].value[end], 0=>NaN), ylims=(0,2) ),
    scatter( collect(1:8), replace( data1["LSB"].value[end], 0=>NaN), ylims=(0,2), ylabel="LSB" ),
    scatter( collect(1:8), replace( data2["LSB"].value[end], 0=>NaN), ylims=(0,2) ),
    leg=:false, layout=(4,2)
)
Out[0]:

We can see what the bit sequences look like when sampling the highest, middle, and lowest bits of the bit grid at different block settings.

Conclusion

We have demonstrated the operation of the block Extract Bits in conjunction with Integer To Bit Conversion. Thus, we showed how masking integers works and how you can get only selected bits at the output, forming a short new sequence from them.

Along with Bus and Mux This is another method that allows you to send many signals over a single signal line. But, of course, this is not the only and not the main application of this block.