Engee documentation
Notebook

Extracting individual bits from a number

In this demonstration, we will show how to work with the block Extract Bits, which allows you to extract bits located in specified positions of the input number.

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

Model description

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

Running the model

In the example, we will feed a constant of the UInt8 type with the value 255 to the input of the Extract Bits block. All bit positions of this eight-bit number are occupied by ones. 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 output scaling during the data type conversion.
  • Treat bit field as an integer - fixed point scaling of input data is ignored and only the stored integer is used to calculate the output data type.

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

Treat bit field as an integer

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

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

image.png

Preserve fixed-point scaling

The model extract_bits_preserve_fixed_point_scaling demonstrates another mode of block operation. In this mode, the sequence of selected bits remains in its place in the digit grid of the number, the other positions are replaced by zeros. We can say that in this way the block realises bit masking in the number.

The MSB signal will now be equal to 0b11000000, i.e. 192.

image.png

Model comparison

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

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 );
Out[0]:
Dict{String, DataFrame} with 4 entries:
  "Mid SB" => 1×2 DataFrame…
  "LSB"    => 1×2 DataFrame…
  "MSB"    => 1×2 DataFrame…
  "Input"  => 1×2 DataFrame
In [ ]:
plot(
    scatter( collect(1:8), replace( data1["Input"].value[end], 0=>NaN), ylims=(0,2), title="Preserve fixed point scaling<br>(маскирование)", 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<br>(выборка)", 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 see how the bit sequences look like when sampling the high, middle and low bits of the bit grid at different block settings.

Conclusion

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

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