Bit Clear — Control Systems/Logic And Bit Operations
Control_Systems/Logic_And_Bit_Operations/Bit_Clear · 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 Clear
Control Systems / Logic And Bit Operations
Forces one bit of its input to 0 and leaves every other bit alone: y = w AND NOT 2i, where i is the Bit Index and w is the input read as a whole number. Applied entry by entry, so a matrix signal is treated element for element and the signal's size is unchanged.
Ports
- Input – the signal u whose bit is to be cleared, of any size [m,n]. It is read as the whole number w = floor(u) – see the first note below.
- Output – y, of the SAME size [m,n] as the input, and always a whole number.
Parameters
- Bit Index – i, which bit to force to 0, counted from 0 at the least significant bit. A whole-number scalar between 0 and 52. Defaults to 0, as in Simulink.
- 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 index is resolved at export time into the
constant 2i and inlined rather than exposed as a tunable parameter,
matching Sum's signs and the rest of this family. Nothing bitwise is emitted
anywhere: every target computes y = w − 2i·b with
b = floor(u/2i) − 2·floor(u/2i+1),
which needs only a floor and two exact divisions by powers of two. The three HDL
targets are fully synthesizable and evaluate nothing in real: in a
Q16.16 word each of those floors is a shift.
Simulink bridge
Import and export, mapped to simulink/Logic and Bit Operations/Bit
Clear. "Bit Index" to iBit as a plain pass-through value; that
is the block's only parameter on either side.
The Simulink block defines no SampleTime parameter, so
"Sampling Time (s)" does not cross – a block left at the inheriting
default loses nothing, and one given an explicit period is reported rather than
silently dropped.
Notes
- Algebraic, with no state: the output depends only on the current input.
- The input is read as its integer part, toward minus infinity. Every signal in this library is a real matrix, and Simulink's own block refuses one outright – it requires an integer data type. So this block takes floor(u) as the whole number whose bits it is discussing, and a fractional part is dropped rather than carried through: an input of 5.7 answers as 5 would. Feed it whole numbers, or put a Rounding Function in front of it and choose the rounding yourself.
- Negative inputs are handled in two's complement, and this is the block where that choice is visible. Bit i of a negative number is the bit of its floor, not of its truncation, and the two disagree: measured against Simulink at i = 3, an input of −5 answers −13. A reading that truncated toward zero would answer −5 and be wrong on every negative sample while looking correct on all the others.
- Not linear – the output is a step function of the input – so the block deliberately carries no state space and model reduction reports it as unmergeable.
- On the three HDL targets 2i must itself be representable in Q16.16, which holds for i up to 14. Above that the fixed-point cores stop agreeing with the other seven; the software targets are unaffected.
- To force a bit to 1 instead, use Bit Set; to combine a whole mask of bits, use Bitwise Operator.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Logic_And_Bit_Operations/Bit_Clear |
| family | Control_Systems/Logic_And_Bit_Operations |
| solver environment class | ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_Clear |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bit_Clear/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_Clear.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Bit_Clear/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Bit_Clear.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 |
|---|---|---|
Bit Index | 0 | iBit |
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 Clear |
| 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 |
|---|---|---|
Bit Index | iBit | passes through |
Caveat (shown to the user): the block's only parameter maps 1:1 onto Simulink's iBit, so the round trip is lossless; Simulink's block requires an INTEGER data type where every ICore signal is a real matrix, so this block reads floor(u) as the whole number whose bits it forces and a fractional input loses its fraction; the Simulink block has NO SampleTime parameter, so "Sampling Time (s)" does not cross
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).
Bit Clear block -- force one bit of the input to 0 y = w - 2^i * b, with w = floor(u) and b bit i of w. That is w AND NOT 2^i, written as arithmetic so it survives to all ten targets without a bitwise type anywhere.
The whole identity, the floor-not-truncation decision, the eight R2026a rows behind it and every one of the ten generators live in ICoreBitFieldBlockBase, shared with Bit Set -- the two blocks differ by one sign. This file is what is genuinely this block's: its Op, its ports, its config, its description, its icon and its Simulink entry.
⚠ THIS IS THE BLOCK WHOSE MEASUREMENT RULES TRUNCATION OUT. At iBit = 3 over int16, Simulink answers -5 -> -13. Reading bit 3 of -5 by truncating toward zero gives b = 0 and an answer of -5; only the FLOOR spelling gives b = 1 and -13. A block built on trunc() would agree on every non-negative sample and be wrong on the negative ones -- a defect no positive-only stimulus could ever reach. The other measured rows, at iBit = 3 over uint8 unless said otherwise: 5 -> 5, 12 -> 4, 217 -> 209; at iBit 0, 5 -> 4; at iBit 7, 217 -> 89.
⚠ SIMULINK'S BLOCK REFUSES A DOUBLE and needs an integer type, which is why the parity testbench casts its stimulus and this block reads floor(u) instead.
Code export: the bit index is resolved at export time into the constant 2^i and inlined, rather than exposed as a tunable parameter -- it is structural, like Sum's signs. All ten targets; see the base for how each spells the three floors.
Algebraic and stateless. No state space -- see the header.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | -2 |
| 0.4 | 0.5 | 0 |
| 0.8 | -2 | -2 |
| 1.2 | 0.5 | 0 |
| 1.6 | -2 | -2 |
| 2 | 0.5 | 0 |
| 2.4 | -2 | -2 |
| 2.8 | 0.5 | 0 |
| 3.2 | -2 | -2 |
| 3.6 | 0.5 | 0 |
| 4 | -2 | -2 |
| 4.4 | 0.5 | 0 |
| 4.8 | -2 | -2 |
| 5.2 | 0.5 | 0 |
Every 4th of 60 samples, from the table stimulus.
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 … 4 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -2 … 0 |
step | Step: 0 -> 1 at t = 1 s | 0 … 0 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · 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__Bit_Clear.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).