Relational Operator — Control Systems/Logic And Bit Operations
Control_Systems/Logic_And_Bit_Operations/Relational_Operator · 2 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.
Relational Operator
Control Systems / Logic and Bit Operations
Compares two numeric signals entry by entry and answers true or false: equal, not equal, less than, less than or equal, greater than or equal, or greater than.
Ports
- u1, u2 – the two signals compared, in that order, of any size [m,n]. Each accepts any numeric type – floating point, integer or boolean – and the two do not have to be the same type: an integer signal may be compared with a floating-point one, because the comparison is over the values. They must be the same size, or one of them may be a scalar, which is then compared against every entry of the other. Text and buses are refused: their value is not a number, so there is nothing here to compare.
- Output (
bool) – the answer, of the inputs' shared size [m,n], carryingICoreBool. It is boolean whatever the inputs carry.
Parameters
- Operator – which comparison is made. This selects the
comparison rather than retuning it, so each option is a separate code path.
- Equal – true where the two are exactly equal.
- Not equal
- Less than
- Less than or equal – the default, as in Simulink.
- Greater than or equal
- Greater than
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Comparing for equality
Equal and Not equal compare the numbers exactly. Two values that a calculation should have made identical often are not – that is a property of floating-point arithmetic and not of this block – so a test for equality between two computed signals is usually better written as a Less than against a small difference.
Simulink's isInf, isNaN and isFinite
Those three are not offered here. They take one input rather than two, so choosing one would change the block's port list, and they ask about a single value's finiteness rather than comparing two signals. Importing a Simulink model that uses one is reported rather than silently mapped to something else.
Code export
All ten targets carry this block – Python, MATLAB, Java, Rust, C, C++, PLC Structured Text, VHDL, Verilog and SystemVerilog. The comparison is fixed into the generated code at export time.
On the three HDL targets the comparison needs no scaling and no
helper: signals are carried in one fixed-point format (Q16.16), and an order
comparison on a fixed-point value is the same comparison on the underlying
integer. Equality is exact for the same reason – both sides have already
been rounded onto the same grid before they reach this block, so Equal
compares two grid points rather than two floats. The result is written as 1.0 or
0.0, and the output port being ICoreBool means the write-time
quantize applies to it as well.
Simulink bridge
Import and export, mapped to simulink/Logic and Bit Operations/Relational
Operator. "Operator" to Operator, one option for one option, so
that round trip is lossless for the six comparisons; "Sampling Time (s)" to
SampleTime, as on every block.
OutDataTypeStr is always written as boolean,
because the output is boolean whatever arrives and has no choice to offer.
InputSameDT is always written as off, which is what
lets the two inputs carry different types – the same freedom this block
gives them. ZeroCross and RndMeth are solver and
fixed-point settings with no counterpart here and do not cross.
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.
- The block produces 1 or 0 and the output port applies the boolean type once, which is what makes the simulation and the generated code agree exactly.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Logic_And_Bit_Operations/Relational_Operator |
| family | Control_Systems/Logic_And_Bit_Operations |
| solver environment class | ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Relational_Operator |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Relational_Operator/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Relational_Operator.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Logic_And_Bit_Operations/Relational_Operator/ICoreBlock_0_Control_Systems_1_Logic_And_Bit_Operations_2_Relational_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++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | u1 |
| 2 | in | ICoreDouble | u2 |
| 3 | out | ICoreBool | — |
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 | Equal%~%Not equal%~%Less than%~%Less than or equal%~%Grea… | Operator |
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/Relational Operator |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
| always set | OutDataTypeStr = boolean, InputSameDT = off |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Operator | Operator | Equal → ==, Not equal → ~=, Less than → <, Less than or equal → <=, Greater than or equal → >=, Greater than → > |
Caveat (shown to the user): the six comparisons map 1:1 onto Simulink's; Simulink's three UNARY predicates (isInf, isNaN, isFinite) are deliberately not offered here -- they take one input rather than two, so they would move the port list, and an imported model using one is reported by the enum table rather than mapped to something else
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).
Relational Operator -- two numeric signals in, one boolean out THE BLOCK EACH OF WHOSE INPUTS ACCEPTS ANY NUMERIC TYPE WHILE ITS OUTPUT IS BOOLEAN WHATEVER ARRIVED. That combination is the reason it exists: a signal's type is otherwise strict end to end, and this is the shape where widening what a port ACCEPTS, without changing what it IS, is the right answer.
ONE COMPARISON, SPELLED SIX WAYS AND SEVEN TIMES. Four of the six operators are written the same in every language this block emits; only equality and inequality differ (
==/!=in C, C++, Java, Rust and Python,==/~=in MATLAB,=/<>in Structured Text), so each generator passes its own two spellings to one shared helper in this file and none of them holds a six-way switch of its own.SEVEN, not ten: the three hardware-description targets have no generator here at all, deliberately -- see the section where they would be.
THE BLOCK NEVER ROUNDS ITS OWN OUTPUT: it returns 1.0 or 0.0 as plain numbers and the output port applies the boolean type once, on the same seam in the simulator and in every generated core.
Sample results#
| t | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | out ICoreBool-Out-0 |
|---|---|---|---|
| 0 | -2 | -2 | 1 |
| 0.04 | 0.5 | 0.5 | 1 |
| 0.08 | -2 | -2 | 1 |
| 0.12 | 0.5 | 0.5 | 1 |
| 0.16 | -2 | -2 | 1 |
| 0.2 | 0.5 | 0.5 | 1 |
| 0.24 | -2 | -2 | 1 |
| 0.28 | 0.5 | 0.5 | 1 |
| 0.32 | -2 | -2 | 1 |
| 0.36 | 0.5 | 0.5 | 1 |
| 0.4 | -2 | -2 | 1 |
| 0.44 | 0.5 | 0.5 | 1 |
| 0.48 | -2 | -2 | 1 |
| 0.52 | 0.5 | 0.5 | 1 |
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) | 1 … 1 |
ramp | Ramp: slope 1 from t = 0 | 1 … 1 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 1 … 1 |
step | Step: 0 -> 1 at t = 1 s | 1 … 1 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.01 · 60 steps · commit 31d36c2c3 · produced by docsSample --out <folder> --blocks Bus_Creator,Bus_Selector,Logical_Operator,Relational_Operator,Bitwise_Operator,Switch --steps 60 · data docs/generated/samples/Control_Systems__Logic_And_Bit_Operations__Relational_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).