Bit To Integer Converter — Control Systems/Logic And Bit Operations
Control_Systems/Logic_And_Bit_Operations/Bit_To_Integer_Converter · 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.
Bit to Integer Converter
Control Systems / Logic And Bit Operations
Packs each group of n consecutive input entries into one output entry, where n is Number of Bits. At 3 bits, most significant first, [1 0 1] becomes 5 unsigned and -3 signed. It is the mirror of Integer to Bit Converter.
It packs in groups, not once per signal: a six-entry input at 3 bits gives a two-entry output, [0 0 1 1 1 1] becoming [1 7]. So the input width must be a whole multiple of n, and the output carries one entry per group.
A bit counts as set when its entry is nonzero, not when it equals exactly one, which is this family's convention throughout.
Ports
- Input – the bits u, a vector: [m,1], [1,n] or a scalar. Its number of entries must be a positive whole multiple of Number of Bits, and a width that is not is reported rather than padded or truncated. A matrix with both dimensions above one is reported too, because which way it would be flattened is exactly the question a user would be guessing at.
- Output – y, one entry per group of n. Its size follows the input's: a column of w entries gives a column of w/n, a row gives a row of w/n.
Parameters
- Number of Bits – how many input entries make one output entry. A whole number from 1 to 32; the default is 3, which is the Simulink block's default too.
- Bit Order – which end of each group is the most significant bit.
- MSB first – the first entry of a group carries 2n-1. The default.
- LSB first – the first entry carries 1; the same group read from the other end.
- Output Signedness – how the most significant bit is read.
- Unsigned – every weight is positive, so the result lies in [0, 2n). The default.
- Signed – the most significant weight is negative, which is exactly two's complement, so the result lies in [-2n-1, 2n-1). At 3 bits, [1 0 1] is -4 + 0 + 1 = -3.
- 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. The bit count, the order and the signedness are resolved at export time into a fixed list of weights, so a generated core carries one accumulate per group with no loop, no index arithmetic and no tunable parameter behind it.
The three HDL targets are genuine synthesizable Q16.16 – the body is a compare against zero and an add per bit. Their fixed-point format holds whole numbers up to about ±32768, so a word wider than 15 bits unsigned (16 signed) produces sums those three columns cannot represent; the seven software targets are exact to the full 32.
Simulink bridge
Import and export, mapped to simulink/Logic and Bit Operations/Bit to Integer
Converter. Number of Bits → nbits, Bit Order →
bitOrder and Output Signedness → signedOutputValues,
each 1:1 and therefore lossless both ways. Simulink's outDtype and
outDtypeSigned select the integer TYPE of the result and have no counterpart
here, every ICore signal being a matrix of doubles, so they are left at their Simulink
defaults.
The rate does NOT cross. That block defines no SampleTime parameter
– verified by set_param against R2026a, which answers "Bit to Integer
Converter block (mask) does not have a parameter named 'SampleTime'" – so
"Sampling Time (s)" stays on the ICore side. Writing it anyway would be a hard error that
aborts the whole generated script rather than a warning that degrades.
Notes
- Algebraic, with no state: the output depends only on the current input.
- Simulink's counterpart takes a boolean input, so a model wiring a double signal into it needs a conversion first; on an ICore wire the nonzero rule does that job directly and no conversion block is needed.
- The output is a different SIZE from the input, and it is fixed for the run. A downstream block that requires its inputs to agree in size must be given signals that do.
- No state space, deliberately. The weighted sum is linear in the bits, but the nonzero test in front of it is not, and the output is a different size from the input; carrying one would offer the block for model-reduction merges it cannot serve.
- To go the other way – one number into a group of bits – use Integer to Bit Converter, whose parameters are the mirror of these.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Logic_And_Bit_Operations/Bit_To_Integer_Converter |
| family | Control_Systems/Logic_And_Bit_Operations |
| solver environment class | ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_To_Integer_Converter |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bit_To_Integer_Converter/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_To_Integer_Converter.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bit_To_Integer_Converter/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_To_Integer_Converter.h |
| default size on canvas | 80 × 70 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | — |
| 2 | out | ICoreDouble | — |
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 variable | Default | Simulink parameter |
|---|---|---|
Number of Bits | 3 | nbits |
Bit Order | MSB first%~%LSB first~~MSB first | bitOrder |
Output Signedness | Unsigned%~%Signed~~Unsigned | signedOutputValues |
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.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/Logic and Bit Operations/Bit to Integer Converter |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Number of Bits | nbits | passes through |
Bit Order | bitOrder | MSB first → MSB first, LSB first → LSB first |
Output Signedness | signedOutputValues | Unsigned → Unsigned, Signed → Signed |
Caveat (shown to the user): Simulink's outDtype and outDtypeSigned select the integer TYPE of the result, which has no counterpart here -- every ICore signal is a matrix of doubles -- so they are left at their Simulink defaults. Simulink's block takes a BOOLEAN input, so a model wiring a double into it needs a conversion first; on an ICore wire the nonzero rule does that job. The rate does not cross: the Simulink block defines no SampleTime parameter, so "Sampling Time (s)" stays on the ICore side
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:
B0no 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).
Bit to Integer Converter -- n consecutive 0/1 entries become one number The mirror of Integer to Bit Converter. Each GROUP of "Number of Bits" consecutive input entries is read as a binary word and packed into one output entry: at 3 bits most significant first, [1 0 1] is 5 unsigned and -3 signed, and LSB first the same entries are 5 and -3 read from the other end. All measured in R2026a.
⚠ IT PACKS IN GROUPS. A six-entry input at 3 bits answers a TWO-entry output -- measured, [0 0 1 1 1 1] gave [1 7] -- so the input width must be a whole multiple of the bit count. A block that packed the whole signal into one number would agree on every input exactly one group wide, which is the only width a careless rig would ever drive, so the check belongs in the block rather than in a test.
ONE ACCUMULATE LOOP, TEN BACKENDS, AND NO SIGNED BRANCH. Two's complement IS the positional sum with the most significant weight taken NEGATIVE -- [1 0 1] signed is -4 + 0 + 1 -- so "Output Signedness" flips the sign of exactly one weight and nothing else changes. Every generator below emits the same list of (weight, input entry) pairs, which is why they cannot disagree about bit order or about which entry is the sign.
A BIT IS SET WHEN ITS ENTRY IS NONZERO, not when it equals one. That is this family's convention -- Combinatorial Logic and Logical Operator both measured it against R2026a -- and it is what lets the block accept the 0/1 doubles an ICore wire actually carries. Simulink's own block takes a boolean input and applies the same rule to it.
Algebraic and stateless. No state space -- see the header.
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.