Документация Engee
Notebook

Извлечение отдельных битов из числа

В этой демонстрации мы покажем, как работать с блоком Extract Bits, который позволяет извлечь биты, расположенные в заданных позициях входного числа.

Этот блок очень полезен при проектировании алгоритмов систем цифровой связи, при моделировании битовых сигнальных линий в системах управления или робототехнике, а также в разных самых задачах графического программирования.

Описание модели

Блок Extract Bits принимает на вход целое число и формирует из него новое число на выходе. В свойствах блоков можно указать, какие биты из входного числа будут скопированы, а какие – нет.

Запуск модели

В примере мы будем подавать на вход блока Extract Bits константу типа UInt8 с значением 255. Все разрядные позиции этого восьмибитного числа заняты единицами. Покажем два режима работы блока Extract Bits:

  • Preserve fixed-point scaling — масштабирование входных данных с фиксированной точкой используется для определения масштабирования на выходе во время преобразования типа данных.
  • Treat bit field as an integer — масштабирование входных данных с фиксированной точкой игнорируется, а для вычисления типа выходных данных используется только сохраненное целое число.

Сейчас мы увидим, чем различается работа обоих методов.

Treat bit field as an integer

Модель extract_bits_treat_bit_fields_as_integer демонстрирует работу того режима, при котором извлеченная последовательность битов становится младшими битами в выходном сигнале блока.

Сигнал MSB, полученный из числа 255 взятием двух старших битов числа, будет равен 0b11 (число 3), поскольку последовательность битов 11 смещается на место битов младшего разряда.

image.png

Preserve fixed-point scaling

Модель extract_bits_preserve_fixed_point_scaling демонстрирует другой режим работы блока. В этом режиме последовательность выбранных битов остается на своем месте в разрядной сетке числа, остальные позиции заменяются нулями. Можно сказать, что таким образом блок реализует маскирование битов в числе.

Сигнал MSB теперь будет равен 0b11000000, то есть 192.

image.png

Сравнение моделей

Запустим обе модели средствами программного управления моделиравнием:

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]:

Мы видим, как выглядят последовательности бит при выборке старших, средних и младших бит разрядной сетки при разных настройках блока.

Заключение

Мы продемонстрировали работу блока Extract Bits в связке с Integer To Bit Conversion. Таким образом мы показали, как работает маскирование целых чисел и как можно получить на выходе только выбранные биты, образовав из них короткую новую последовательность.

Наряду с Bus и Mux это еще один способ, который позволяет пересылать много сигналов по одной сигнальной линии. Но, конечно, это не единственное и не главное применение этого блока.

Блоки, использованные в примере