Generated reference › Float Extract Bits — Control Systems/Logic And Bit Operations
kind: generated#block#control-systems-logic-and-bit-operations

Float Extract Bits — Control Systems/Logic And Bit Operations

s e m

Control_Systems/Logic_And_Bit_Operations/Float_Extract_Bits · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Description#

The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.

Float Extract Bits

Control Systems / Logic And Bit Operations

Reads its input as an IEEE-754 floating-point number and answers a contiguous field of the bits that represent it: y = (bits(u) ÷ 2low) mod 2n, with bit 0 the LEAST significant bit. The word is one sign bit at the top, then E biased exponent bits, then M mantissa bits – 1/8/23 for a single, 1/11/52 for a double. Applied entry by entry, so a matrix signal keeps its size.

Ports

  • Input – the number u, of any size [m,n]. It is first ROUNDED to the chosen float type, exactly as feeding Simulink's block through a Data Type Conversion does, and the bits of that rounded value are what is read.
  • Output – y, of the SAME size [m,n], carrying the requested field as an ordinary real signal.

Parameters

  • Output Mode – which field is taken. This selects the field rather than retuning it, so each option is its own code path.
    • All bits – the whole word: low = 0, n = W. The default, as in Simulink. On a double this is a 64-bit field and is refused – see Notes.
    • Range of bits – the window named by Bit Range.
    • Sign – the top bit alone: 1 for a negative value, 0 otherwise. A negative zero reports 1, as IEEE-754 says and as Simulink answers.
    • Mantissa – the low M bits, with no implied leading one.
    • Exponent – the E BIASED exponent bits: 127 for 1.0 as a single, 1023 as a double. Zero and the subnormals report 0; an infinity or a NaN reports all ones.
  • Bit Range – a two-entry [low high] pair, INCLUSIVE at both ends, used only in Range of bits. The low bound must not exceed the high one – Simulink makes that a hard error and so does this block. A window reaching above the top of the word reads zeros there.
  • Input Float Type – single (8 exponent, 23 mantissa) or double (11 exponent, 52 mantissa): which layout the bits are read in, and which type the input is rounded to first. This has no Simulink parameter behind it – see Simulink bridge.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text – but not every one of them in every configuration, and a target that cannot carry the configuration refuses it by name rather than exporting arithmetic that overflows in silence.

  • The three HDL targets carry this library's arithmetic in Q16.16 fixed point, so the value reaching the generated body has already been quantized and has no IEEE-754 mantissa left to read – bits below 2−16 are gone. What survives quantization is the MAGNITUDE, which is what the sign and the exponent are made of. So those three implement any field lying entirely at or above bit M – Sign, Exponent, and a Range of bits that does not reach into the mantissa – and refuse the rest. They also refuse a field wider than 15 bits, because the answer goes back out through a Q16.16 port that tops out at 32767.
  • PLC Structured Text has a real LREAL and keeps every field the software targets do, up to the 2147483647 its TRUNC yields as a DINT. So it refuses All bits and a double's Mantissa, and carries the rest.
  • The seven software targets carry every configuration the block accepts at all.

The field, the layout and every power of two are resolved when the model is built and inlined as literals; nothing here is a tunable parameter on the generated core.

Simulink bridge

Import and export, mapped to simulink/Logic and Bit Operations/Float Extract Bits. Output Mode → OutputMode and Bit Range → BitRange, both 1:1 and lossless: the enum table is Simulink's own five strings.

"Input Float Type" does NOT cross, and is reported rather than dropped. In Simulink the layout comes from the input SIGNAL's data type, which is a property of the wire and not a parameter of the block, so there is no set_param that could carry it – a model crossing either way needs a Data Type Conversion of the matching type in front of the block. This is the same gap Extract Bits carries for its word length, and for the same reason: every ICore wire is a matrix of doubles.

The rate does NOT cross. That block defines no SampleTime parameter – verified by set_param against R2026a, which answers "FloatExtractBits block does not have a parameter named 'SampleTime'" – so "Sampling Time (s)" stays on the ICore side.

Notes

  • Algebraic and stateless. Deliberately carries no state space: reading a bit field is a piecewise-constant function of the input, so there is no A/B/C/D that represents it.
  • A field wider than 53 bits is refused by the block itself, in every language and in the live run, because an ICore signal carries whole numbers exactly only that far. That is exactly All bits on a double, whose word is 64 bits wide. On a single the whole 32-bit word fits exactly and All bits is offered.
  • Negative zero is the one place the HDL targets cannot agree with the others. IEEE gives −0 a sign bit of 1 and Simulink reports it; Q16.16 fixed point has no negative zero at all, so an HDL core reports 0 there. Every other input agrees exactly. This is the port's limit rather than the block's, and it is stated here because nothing else would reveal it.
  • An HDL core reads the exponent of the QUANTIZED value. Where the input is exactly representable in Q16.16 – any multiple of 2−16 below 32768 – that is the same number the other targets read. Where it is not, the two can differ by one for a sample lying within a quantum of a power of two.
  • An infinity reports an exponent of all ones and a mantissa of zero; a NaN reports all ones and a quiet-NaN mantissa. A NaN's own payload does not survive.

Code facts#

FactValue
registered typeControl_Systems/Logic_And_Bit_Operations/Float_Extract_Bits
familyControl_Systems/Logic_And_Bit_Operations
solver environment classICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Float_Extract_Bits
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Float_Extract_Bits/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Float_Extract_Bits.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Float_Extract_Bits/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Float_Extract_Bits.h
default size on canvas100 × 70 px
ports at insert1 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble—
2outICoreDouble—

Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.

Configuration variables#

Config variableDefaultSimulink parameter
Output ModeAll bits%~%Range of bits%~%Sign%~%Mantissa%~%Exponent~~Al…OutputMode
Bit Range[0 15]BitRange
Input Float Typesingle (8 exponent, 23 mantissa)%~%double (11 exponent, 5…not crossed

Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.

supportSupport::Both
Simulink pathsimulink/Logic and Bit Operations/Float Extract Bits
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
deliberately not crossedInput Float Type
ICore configSimulink parameterValue translation
Output ModeOutputModeAll bits → All bits, Range of bits → Range of bits, Sign → Sign, Mantissa → Mantissa, Exponent → Exponent
Bit RangeBitRangepasses through

Caveat (shown to the user): "Input Float Type" has no Simulink parameter behind it -- there the exponent and mantissa widths come from the input signal's own float type, so a model crossing either way needs a Data Type Conversion to the matching type in front of the block; the Simulink block has NO SampleTime parameter, so "Sampling Time (s)" does not cross either. A configuration whose field is wider than 53 bits -- which is "All bits" on a double -- is refused by this block in every language, an ICore signal carrying whole numbers exactly only that far

Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h

Description vs code#

The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:

  • B0 no sample under docs/generated/samples/ — nothing to cross-check (P8.1)

The verdict above is tools/docs/check_block_descriptions.py (P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.

File banner (developer view)#

The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).

Float Extract Bits -- a field of the IEEE-754 bits that represent the input y = (bits(u) / 2^low) mod 2^n, entry by entry. See the header for the layout, for why the fields are built by arithmetic rather than by a reinterpret-cast, and for the two places the block stops and says so instead of answering.

THE FIELD IS ASSEMBLED FROM THREE PIECES, WHICH IS WHAT MAKES THE HDL RULE A LINE RATHER THAN A SPECIAL CASE. A float's word is three contiguous components -- the mantissa at bit 0, the biased exponent at bit M, the sign at bit W-1 -- so a requested window [low, high] takes a slice of each one it OVERLAPS and adds them at their own weights. partFor() decides each slice once, at config-load time, and every one of the ten generators emits only the pieces its part list says are needed. A target that cannot supply the mantissa is then a target that refuses exactly the configurations whose mantissa part is needed, which is one predicate rather than a table of modes.

ONE ALGORITHM, TEN TIMES, ON PURPOSE. The sign, exponent and mantissa come from normalizing |v| into [1,2) by halving and doubling -- operations that are exact in binary floating point -- and reading off what is left. A reinterpret-cast would be shorter in five of the ten targets, unavailable in the other five, and would need a different correctness argument in each. This way the reference in compute_h and the nine translations of it are visibly the same arithmetic.

Sample results#

No sample run is committed for this block. Samples come from the headless harness (DOCS_PLAN.md P8.1) into docs/generated/samples/; until one exists this block's behaviour is witnessed by the parity and export-verification suites, not by a plot here.