Engee 文档
Notebook

从数字中提取单个比特

在本演示中,我们将介绍如何使用程序块Extract Bits ,它允许您提取输入数字指定位置上的位。

在设计数字通信系统算法、为控制系统或机器人技术中的位信号线建模以及执行各种图形编程任务时,该程序块非常有用。

模型描述

程序块Extract Bits 将一个整数作为输入,并从中生成一个新数字作为输出。在程序块属性中,您可以指定输入数字的哪些位将被复制,哪些位不会被复制。

运行模型

在示例中,我们将向Extract Bits 模块的输入端输入一个UInt8 类型的常量,其值为 255。这个八位数的所有位均为 1。下面我们来展示程序块Extract Bits 的两种运行模式:

*Preserve fixed-point scaling - 在数据类型转换过程中,输入数据的定点缩放用于确定输出缩放。 *Treat bit field as an integer - 忽略输入数据的定点缩放,仅使用存储的整数计算输出数据类型。

现在我们来看看这两种方法的操作有何不同。

将位字段视为整数

extract_bits_treat_bit_fields_as_integer 模型演示了提取的比特序列成为块输出信号中低阶比特的运行模式。

从数字 255 中提取高两位后得到的信号MSB 将等于0b11 (数字 3),因为位序列11 被移到了低位。

image.png

保留定点缩放

extract_bits_preserve_fixed_point_scaling 机型演示了另一种块操作模式。在这种模式下,被选中的比特序列将保留在数字的数位网格中,其他位置则由 0 代替。我们可以说,通过这种方式,程序块实现了数字中的位屏蔽。

现在,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 结合使用。因此,我们展示了屏蔽整数的工作原理,以及如何通过将整数组成一个新的短序列,在输出端只获取选定的比特。

BusMux 一样,这是另一种可以通过一条信号线发送多个信号的方法。当然,这并不是该程序块的唯一或主要应用。

示例中使用的块