Bitwise Operator — Control Systems/Logic And Bit Operations
Control_Systems/Logic_And_Bit_Operations/Bitwise_Operator · 2 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, 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.
Bitwise Operator
Control Systems / Logic and Bit Operations
Combines integer signals bit by bit: AND, OR, NAND, NOR and XOR over as many inputs as you give it, or NOT over one. The work is done entry by entry, so two [2,3] signals produce a [2,3] answer.
Ports
- Inputs (
u32by default) – two by default, and the count is user-editable. Every input carries the integer type chosen below and nothing else, because a bit operation is defined on a width. They must all be the same size [m,n], or be scalars, which are then combined with every entry of the others. NOT takes exactly one input; the other five take at least two. - Output (
u32by default) – the result, of the inputs' shared size [m,n], carrying the same integer type.
Feeding it another type
Every port on this block carries one integer type, so a floating-point or differently-sized signal reaches it through a Data Type Conversion block – which puts the change of width on the canvas where you can see it. That is also Simulink's rule: its Bitwise Operator requires its inputs to share one integer type and gives that type back.
Parameters
- Operator – which combination is taken. This selects the
operation rather than retuning it, so each option is a separate code path.
- AND – a bit is set where it is set in every input. The default, as in Simulink.
- OR – set where it is set in any input.
- NAND – the negation of AND.
- NOR – the negation of OR.
- XOR – set where an ODD number of inputs has it set, which is what chaining exclusive-or across several inputs means.
- NOT – every bit of a single input flipped.
- Operate on data type – the integer type every port carries, and therefore the width the result is taken to. The list is every integer type the application knows, so it grows when the application does. Defaults to a 32-bit unsigned integer.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
What the width does to the answer
The result is taken to the chosen width when it is stored, which is where NOT becomes interesting: on an 8-bit unsigned output, NOT of 5 is 250, and on an 8-bit signed output the same operation gives −6. Those are the same bits read two ways, and choosing the type is choosing which reading you get. Nothing is clamped: a result that does not fit wraps around, which is what a fixed-width integer does everywhere.
Code export
Python, MATLAB, Java, Rust, C, C++ and PLC Structured Text carry this block. The operator and the width are fixed into the generated code at export time.
VHDL, Verilog and SystemVerilog are not applicable for this block at any setting, and are refused by name at export time with the reason rather than producing a number that would differ from the simulation. Those three targets carry every signal in one fixed-point format and do not yet apply a signal's type to it, and every port on this block is an integer. The refusal is recorded as "not applicable", never as a failure.
Simulink bridge
Import and export, mapped to simulink/Logic and Bit Operations/Bitwise
Operator. "Operator" to logicop, one option for one option
(AND, OR, NAND, NOR,
XOR, NOT), so that round trip is lossless; the input
port count becomes Simulink's NumInputPorts number and an imported
count becomes this port list.
UseBitMask is always written as off: Simulink's
block can instead combine ONE input against a stored mask, which here is a
Constant wired into a second port – visible on the canvas, and one
fewer parameter to keep in step. Operate on data type does not cross,
because Simulink's block has no data-type parameter at all – it takes the
type from the signal reaching it, which is the same type this block's ports
carry, so the two agree without a parameter. Simulink's block has no
sampling-time parameter, so a rate set here stays on this side and is
reported rather than silently dropped.
Notes
- Algebraic, with no state: the output depends only on the current inputs.
- Not linear, so the block deliberately carries no state space and model reduction reports it as unmergeable.
- A 64-bit integer type is exact only to about 9 007 199 254 740 992 (253): values are carried as 64-bit floats during a run, and a 64-bit float cannot hold every 64-bit integer. The narrower types are exact.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Logic_And_Bit_Operations/Bitwise_Operator |
| family | Control_Systems/Logic_And_Bit_Operations |
| solver environment class | ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bitwise_Operator |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bitwise_Operator/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bitwise_Operator.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bitwise_Operator/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bitwise_Operator.h |
| default size on canvas | 80 × 70 px |
| ports at insert | 2 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreUInt32 | — |
| 2 | in | ICoreUInt32 | — |
| 3 | out | ICoreUInt32 | — |
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 |
|---|---|---|
Operator | AND%~%OR%~%NAND%~%NOR%~%XOR%~%NOT~~AND | logicop |
Operate on data type | typeComboSpec() | 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.
Simulink bridge#
| support | Support::Both |
| Simulink path | simulink/Logic and Bit Operations/Bitwise Operator |
| port-count rule | PortsParam::BitwiseNumInputPorts |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| deliberately not crossed | Operate on data type |
| always set | UseBitMask = off |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Operator | logicop | AND → AND, OR → OR, NAND → NAND, NOR → NOR, XOR → XOR, NOT → NOT |
Caveat (shown to the user): the six operators map 1:1 onto Simulink's logicop; there is deliberately no NXOR, because Simulink's Bitwise Operator does not offer one. The mask mode is not offered either -- combining one input against a stored constant is a Constant wired into a second port here, which is visible on the canvas
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
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).
Bitwise Operator -- AND, OR, NAND, NOR, XOR over N integer inputs, or NOT over one THE BLOCK THAT PUTS THE APPLICATION'S WRAP RULE IN FRONT OF SOMETHING THAT CAN DISAGREE WITH IT. Every other typed block in the library either passes a value through unchanged or produces one already inside its type's range. This one routinely produces values that are not: NOT of a small positive integer is a large negative one, and the WIDTH is what decides what comes back.
AND IT DOES NOT APPLY THAT WIDTH ITSELF. The block computes the bit operation on a SIXTY-FOUR-BIT SIGNED integer in every language, and the OUTPUT PORT truncates and wraps the result to the configured width, once, exactly as it does for every block. That is not a shortcut, it is what makes the answer right for all eight widths from one expression:
8-bit signed ~5 at 64 bits -> -6 port wraps -> -6 8-bit unsigned ~5 at 64 bits -> -6 port wraps -> 250 32-bit unsigned ~4294967290 at 64 bits -> -4294967291 port wraps -> 5 32-bit signed -5 & -3 at 64 bits -> -7 port wraps -> -7
Sign extension to 64 bits preserves the two's-complement pattern of a signed operand, and an unsigned operand is non-negative and therefore already itself. Writing the mask into each generator instead would put the width rule in seven places and leave the port applying it an eighth time.
ONE FOLD, SPELLED SEVEN WAYS. Six of the seven languages spell the operators infix and MATLAB spells them as functions, so the shared helper in this file takes a flag for which and every generator hands it its own three tokens.
Sample results#
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 0 |
ramp | Ramp: slope 1 from t = 0 | 0 … 0 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 0 … 0 |
table | Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample | 0 … 0 |
Plotted: step — Step: 0 -> 1 at t = 1 s
Category dynamic · sample time 0.1 · 60 steps · commit 3c100aff6f27235305db4ad4d572f32e342718ad · produced by docsSample --out <folder> --blocks Shift_Arithmetic Bit_Set Bit_Clear Bitwise_Operator --steps 60 · data docs/generated/samples/Control_Systems__Logic_And_Bit_Operations__Bitwise_Operator.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).