Doc Block — Control Systems/Model Wide Utilities
Control_Systems/Model_Wide_Utilities/Doc_Block · 0 input / 0 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.
Doc Block
Control Systems / Model Wide Utilities
Free text that travels with the model: it shows on the block's face and is carried into the generated code as a comment, in each target language's own syntax. It has no ports, no state and no arithmetic – it computes nothing at all.
Ports
- None. Not one input, not one output.
When to use this rather than a canvas note
ICore already has canvas annotations, and for a remark pinned to a corner of a diagram they are still the right tool. This block earns its place on the one thing they cannot do: it is part of the model, so it is copied with a subsystem, listed among the blocks, and emitted into every exported core. Put a rationale here when it has to survive the trip into the C or VHDL somebody else reads.
Parameters
- Text – the note, edited in the code editor so it can run to many lines. Line breaks are kept.
- Show On Face –
onpaints the text on the block,offkeeps it in the dialog only. A long note is better kept off the face, where it would make the block enormous. - Emit In Generated Code –
onwrites the text into every exported target as a comment;offkeeps it in the model only. This is Simulink'sECoderFlagunder a name that says what it does. - Sampling Time (s) – present on every block, and inert here: this block does nothing per step, so its rate cannot be observed.
Code export
All ten targets: Python (#), MATLAB
(%), Java, C, C++, Rust, Verilog
and SystemVerilog (//), VHDL (--) and
PLC Structured Text ((* … *)). One comment line per line
of the note, so the shape of the text is preserved.
⚠ PLC Structured Text has its text neutralised, and it is the one target
that needs it. ST's comment form is (* … *), so a
*) typed anywhere in the note would close the comment early and leave
the rest of the prose as ST source – a compile error in a file nobody reads
unless it fails. Any *) is emitted as * ). The nine
line-comment languages need no such care: nothing in a line of text can end a
//, #, % or -- comment early.
With Emit In Generated Code off, the block still emits its (empty) function – an empty body would abort the whole model's export, not just skip this block.
Code-export verification
This block is excluded from the code-export verification matrix, by name,
in ICoreParityRigLibrary::unriggableTypes(). It has no ports and
computes nothing, so there is no signal for the verifier to record or compare on
either side.
Simulink bridge
None, and the reason is in the Simulink block rather than in this one.
Measured on R2026a: Simulink's DocBlock is a masked SubSystem
(MaskType=DocBlock) with ZERO ports, no SampleTime, and
it is VIRTUAL – a model holding one and nothing else refuses to run with
"contains no blocks or all blocks are virtual". Its two parameters are
DocumentType (Text/RTF/HTML) and ECoderFlag, and
the text itself is not a parameter at all: Simulink keeps it in a file
beside the model. So there is nothing for a bridge to carry even in principle, and
a model exchanged through one arrives with the note missing rather than empty.
ICore stores the text IN the block, which is the difference worth knowing.
Notes
- The text is prose, never an expression. Text is not resolved from the variables space, so a variable that shares a word with the note leaves the note alone.
- The face is painted once per run, when the block's configuration is loaded: the text cannot change during a run, so nothing is repainted per step.
- An empty Text is allowed and emits no comment – only the block's
empty function (and, on MATLAB, its
% (DocBlock)marker line), for the reason under Code export. - The dialog does not let you add a port, and a DocBlock that somehow carries one refuses to run: "Invalid number of ports at DocBlock: <path>. A DocBlock has no ports at all."
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Model_Wide_Utilities/Doc_Block |
| family | Control_Systems/Model_Wide_Utilities |
| solver environment class | ICoreBlock_0_Control_Systems_1_Model_Wide_Utilities_2_Doc_Block |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Model_Wide_Utilities/Doc_Block/ICoreBlock_0_Control_Systems_1_Model_Wide_Utilities_2_Doc_Block.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Model_Wide_Utilities/Doc_Block/ICoreBlock_0_Control_Systems_1_Model_Wide_Utilities_2_Doc_Block.h |
| default size on canvas | 140 × 80 px |
| ports at insert | 0 in, 0 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
The constructor creates no port explicitly — the port list comes from registerInitialPorts (0 in, 0 out) or from the block's configuration.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Text | DEFAULT_TEXT | — |
Show On Face | on%~%off~~on | — |
Emit In Generated Code | on%~%off~~on | — |
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::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): Simulink's DocBlock is a masked SubSystem (MaskType=DocBlock) with ZERO ports of any kind, no SampleTime, and it is VIRTUAL - measured on R2026a, where a model holding one and nothing else refuses to run with "contains no blocks or all blocks are virtual". Its two parameters are DocumentType (Text/RTF/HTML) and ECoderFlag, and THE TEXT ITSELF IS NOT A PARAMETER: Simulink keeps it in a file beside the model, so there is nothing for a bridge to carry even in principle and an exchanged model would arrive with the note missing rather than empty. ICore stores the text in the block instead, so this is a DIFFERENT block from the Simulink one rather than a mapping of it, and it is reported on exchange rather than asserted
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).
DocBlock -- free text that travels with the model AND reaches the generated code Zero ports, no state, no arithmetic. "Text" holds the note; "Show On Face" puts it on the block; "Emit In Generated Code" carries it into all ten targets as a comment in each one's own syntax.
⚠ WHY IT IS A BLOCK AND NOT A CANVAS NOTE. ICore already has annotations (ICoreAPIs::createNote), and the board deliberately left this row open as a design question between the two. The answer this build gives is the one thing an annotation cannot do: a DocBlock is part of the MODEL, so it is copied with a subsystem, listed among the blocks, and EMITTED INTO EVERY EXPORTED CORE. A rationale that has to survive the trip into the C or VHDL a customer reads belongs in a block; a label pinned to the canvas does not.
⚠ AN EMPTY BODY ABORTS THE WHOLE EXPORT. Every parser does
if (body.empty())-> logError("Export to <lang> is not supported for block: ...") and returns "", failing the ENTIRE model's export rather than skipping the block (ICoreCParser.cpp:511 and its nine siblings). So every generator below emits its function shell unconditionally, and "Emit In Generated Code = off" removes the COMMENT, never the function.⚠ MEASURED on R2026a (2026-09-17): Simulink's DocBlock is a masked SubSystem, MaskType=DocBlock, ZERO ports on both sides, no SampleTime, and VIRTUAL -- a model holding one and nothing else refuses to run with "contains no blocks or all blocks are virtual". Two parameters, DocumentType (Text/RTF/HTML) and ECoderFlag. The TEXT ITSELF IS NOT A PARAMETER: Simulink keeps it in a file beside the model, which is why the dialog has no field for it and why nothing about the note could cross a bridge even if one existed.
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.