HAL Architecture Specification
Introduction
The Hardware Abstraction Layer (HAL) provides a software-visible representation of openENOC hardware components and defines a standardized mechanism for accessing their Control and Status Registers (CSRs). The HAL serves as the primary interface between software and hardware, enabling configuration, monitoring, diagnostics, and runtime control of openENOC subsystems.
This document specifies the HAL architecture and CSR organization for the openENOC Switch and the openENOC Endpoint Interface. The described CSR definitions establish a common programming model for software components and serve as the authoritative reference for hardware/software integration.
CSR Specification Methodology
Within this flow, Control and Status Registers are defined using Accellera’s SystemRDL 2.0 as the authoritative specification format for all openENOC hardware components.
For artefact generation, the openENOC toolchain is based on PeakRDL, which processes the SystemRDL description and produces the corresponding CSR-related outputs used throughout the build and verification flow. Since the current PeakRDL implementation does not support all features of the SystemRDL 2.0 standard, CSR definitions are written with this limitation in mind to ensure that the complete register specification can be translated into all required generated artefacts without manual intervention or post-processing.
openENOC Switch HAL Architecture
The openENOC Switch provides frame-forwarding and management functionality within the openENOC system. Software access to switch resources is provided through the openENOC Control Interface, which exposes a memory-mapped CSR space.
The switch HAL defines the software-visible representation of switch functionality and provides a consistent programming model independent of implementation-specific details.
Architecture
The switch HAL is organized around a CSR-based management interface that exposes configuration, status, monitoring, and diagnostic functionality. Software components interact with switch resources through register accesses performed over the openENOC Control Interface. The HAL architecture establishes a clear separation between software-visible behavior and the underlying frame-forwarding implementation, allowing internal switch architectures to evolve while maintaining software compatibility.
A central configuration aspect of the switch HAL is the selection of the switch operating mode. In unmanaged mode, the switch operates autonomously and forwarding state is maintained by internal hardware logic. In this mode, the switch may learn forwarding table entries from observed traffic and update its forwarding state without software intervention. In managed mode, forwarding behavior is controlled through software-visible configuration mechanisms exposed by the openENOC Control Interface. This allows an external processor to populate, update, inspect, or invalidate forwarding table entries according to system-specific requirements.
The operating mode is controlled through switch configuration registers. These registers define whether the switch operates autonomously or under software control, and they provide the foundation for additional management functions such as forwarding table updates, status inspection, diagnostics, and event handling. Status registers expose the current operational state of the switch and allow software to determine whether the switch is active, idle, paused, or operating under a specific management mode.
The default forwarding behavior for frames that do not match any enabled forwarding table entry is defined through a dedicated register containing a destination interface bitmap. This register specifies the set of output interfaces to which unmatched frames shall be forwarded. In managed mode, this mechanism allows unmatched frames to be redirected toward a switch controller implemented on one of the openENOC endpoints. Such frames are delivered to the controller using the standard openENOC Endpoint Interface, preserving the same data-plane abstraction used by other endpoint-to-network communication.
Since forwarding table updates may affect the active forwarding behavior of the switch, the HAL includes a switch-level flow control mechanism used during managed reconfiguration. This mechanism is exposed through a Flow Control Register and allows software to temporarily stop or pause the flow of frames through the switch before modifying forwarding state. After the pause request is issued, software can observe the corresponding status indication to determine when the switch has reached a safe state for table modification.
Once the switch is paused, software may update forwarding table entries through the CSR space without interfering with active frame forwarding. After the update sequence is complete, software releases the pause condition and normal forwarding operation resumes. This mechanism provides a simple and deterministic way to perform controlled forwarding table reconfiguration while avoiding inconsistent lookup behavior during partial updates.
The flow control mechanism described here is local to switch management and should not be confused with link-level or protocol-level flow control. Its purpose is to coordinate software-driven CSR updates with the internal forwarding pipeline of the switch.
In managed mode, the HAL therefore provides both configuration access and operational control over the switch forwarding behavior. In unmanaged mode, the same hardware may operate without software intervention, and the openENOC Control Interface may be omitted if no external configuration or monitoring functionality is required.
Forwarding Table
A central software-visible structure of the openENOC Switch is the forwarding table, which defines how frames are forwarded based on their destination MAC address. The table is exposed through the CSR space and can be configured by software using the openENOC Control Interface.
The forwarding table contains entries aligned to a 32-bit data bus. Each forwarding table entry is represented in the CSR space by fields containing a destination MAC address, an N-bit destination interface bitmap, a single enable bit, and padding bits required for alignment to the 32-bit bus width. The destination interface bitmap defines the set of output interfaces to which a matching frame shall be forwarded.
Example forwarding table for an 8-port openENOC Switch
The figure illustrates an example forwarding table for an openENOC Switch with 8 ports. The table contains several representative forwarding rules. Rule (1) defines unicast forwarding of frames with destination address 0x020E0C000011 to the first output interface. Rule (2) represents a disabled unicast rule that remains present in the table but is not applied during forwarding lookup. Rule (3) defines multicast forwarding of frames with destination address 0x030E0C330000 to the first, third, fifth, and seventh output interfaces. Rule (4) defines frame dropping for destination address 0x020E0C123456 by means of an enabled entry with an empty destination interface bitmap. Rule (M) defines the broadcast forwarding rule for frames with destination address 0xFFFFFFFFFFFF.
Register Definitions and CSR Memory Map
The SystemRDL source shown below defines the CSR structure of the openENOC Switch. This source file is the maintained register specification used by the PeakRDL-based generation flow.
1// SPDX-FileCopyrightText: 2026 Enio Kaljic
2// SPDX-License-Identifier: CERN-OHL-S-2.0
3
4addrmap openenoc_switch #(
5 longint unsigned NUM_OF_INTERFACES = 1,
6 longint unsigned TABLE_DEPTH = 1,
7 string INST_NAME = "openenoc_switch"
8) {
9 name = INST_NAME;
10 desc = "Control and status register map for an openENOC Switch instance. It includes configuration registers and a forwarding table used to map destination MAC address keys to output interface selections for frame forwarding.";
11
12 littleendian;
13 default accesswidth = 32;
14 default regwidth = 32;
15 default alignment = 4;
16 addressing = regalign;
17
18 reg info {
19 name = {INST_NAME, ".info"};
20 desc = "Read-only information register for this openENOC Switch instance.";
21
22 field {
23 name = {INST_NAME, ".info.num_of_interfaces[21:16]"};
24 desc = "Number of interfaces in this openENOC Switch instance. This field reflects the NUM_OF_INTERFACES parameter value.";
25
26 sw = r;
27 hw = r;
28 } num_of_interfaces[21:16] = NUM_OF_INTERFACES;
29
30 field {
31 name = {INST_NAME, ".info.table_depth[15:0]"};
32 desc = "Depth of the forwarding table in this openENOC Switch instance. This field reflects the TABLE_DEPTH parameter value.";
33
34 sw = r;
35 hw = r;
36 } table_depth[15:0] = TABLE_DEPTH;
37 } info;
38
39 reg forwarding_control {
40 name = {INST_NAME, ".forwarding_control"};
41 desc = "Forwarding control register for the openENOC Switch instance.";
42
43 field {
44 name = {INST_NAME, ".forwarding_control.operation_mode[0:0]"};
45 desc = "Mode of operation for the openENOC Switch instance. When set to 1, the switch operates in managed mode, allowing software to configure the forwarding table and control forwarding operations. When set to 0, the switch operates in unmanaged mode, where forwarding state is maintained autonomously by internal hardware logic without software intervention.";
46
47 sw = rw;
48 hw = r;
49 } operation_mode[0:0] = 0;
50
51 field {
52 name = {INST_NAME, ".forwarding_control.pause_request[7:7]"};
53 desc = "Pause request for the forwarding logic. When set, this field requests the switch to pause frame forwarding and clear its internal pipeline before forwarding table updates are performed.";
54
55
56 sw = rw;
57 hw = r;
58 } pause_request[7:7] = 0;
59
60 field {
61 name = {INST_NAME, ".forwarding_control.pause_done[15:15]"};
62 desc = "Pause done status. When set, this field indicates that the switch has paused frame forwarding and reached a safe state for forwarding table modification.";
63
64 sw = r;
65 hw = w;
66 } pause_done[15:15];
67 } forwarding_control;
68
69 reg default_forwarding {
70 name = {INST_NAME, ".default_forwarding"};
71 desc = "Defines the destination interface or interfaces for frames that do not match any enabled forwarding table entry.";
72
73 field {
74 name = {INST_NAME, ".default_forwarding.bitmap[NUM_OF_INTERFACES-1:0]"};
75 desc = "Bitmap selecting the output interface or interfaces to which frames that do not match any enabled forwarding table entry are forwarded. Bit NUM_OF_INTERFACES-1, the MSB, corresponds to the first interface; bit 0 corresponds to the last interface.";
76
77 sw = rw;
78 hw = r;
79 } bitmap[NUM_OF_INTERFACES-1:0] = 0;
80 } default_forwarding;
81
82 external regfile forwarding_table {
83 name = {INST_NAME, ".forwarding_table"};
84 desc = "Forwarding table used to map MAC addresses to output interface selections for frame forwarding.";
85
86 regfile entry {
87 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1]"};
88 desc = "Forwarding table entry containing the MAC address key, output interface selection, and entry configuration.";
89
90 reg mac_address {
91 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].mac_address"};
92 desc = "48-bit destination MAC address used as the key for this forwarding table entry.";
93
94 regwidth = 64;
95
96 field {
97 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].mac_address.hi_word[47:32]"};
98 desc = "Upper 16 bits [47:32] of the 48-bit MAC address stored in this forwarding table entry.";
99
100 sw = rw;
101 hw = rw;
102 } hi_word[47:32];
103
104 field {
105 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].mac_address.lo_word[31:0]"};
106 desc = "Lower 32 bits [31:0] of the 48-bit MAC address stored in this forwarding table entry.";
107
108 sw = rw;
109 hw = rw;
110 } lo_word[31:0];
111 } mac_address;
112
113 reg iface {
114 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].iface"};
115 desc = "Forwarding interface information associated with this forwarding table entry.";
116
117 field {
118 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].iface.bitmap[NUM_OF_INTERFACES-1:0]"};
119 desc = "Bitmap selecting the output interface or interfaces to which a matching frame is forwarded. Bit NUM_OF_INTERFACES-1, the MSB, corresponds to the first interface; bit 0 corresponds to the last interface.";
120
121 sw = rw;
122 hw = rw;
123 } bitmap[NUM_OF_INTERFACES-1:0];
124 } iface;
125
126 reg config {
127 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].config"};
128 desc = "Configuration information associated with this forwarding table entry.";
129
130 field {
131 name = {INST_NAME, ".forwarding_table.entry[0..TABLE_DEPTH-1].config.enabled"};
132 desc = "Enables this forwarding table entry. When cleared, the entry is ignored during forwarding table lookup.";
133
134 sw = rw;
135 hw = rw;
136 } enabled;
137 } config;
138 } entry[TABLE_DEPTH];
139 } forwarding_table;
140};
The openENOC Switch CSR memory map and detailed register documentation are derived directly from this SystemRDL specification. The generated CSR documentation provides the corresponding human-readable description of the register hierarchy, address offsets, field layouts, access permissions, reset values, and associated register semantics.
The complete generated CSR documentation is available in openenoc_switch address map.
openENOC Endpoint Interface HAL Architecture
The openENOC Endpoint Interface provides the connection between processing elements and the openENOC network. It exposes endpoint control, status monitoring, and communication management functionality through a dedicated CSR space.
The endpoint HAL establishes a uniform software interface for accessing endpoint resources and controlling interactions with the network.
Architecture
The endpoint HAL is organized around a CSR-based management interface that exposes endpoint configuration, software-visible stream access, remote peer configuration, DMA control, and a virtual remote-memory region. Software components interact with endpoint resources through register accesses performed over the openENOC Control Interface. The HAL architecture establishes a clear separation between software-visible endpoint behavior and the underlying oETP frame handling, allowing internal buffering, DMA scheduling, and protocol processing logic to evolve while maintaining software compatibility.
A central configuration aspect of the endpoint HAL is the description of the local endpoint instance and the set of remote peers that it can access. The read-only information register exposes implementation parameters such as the total depth of the virtual remote-memory region and the number of supported remote peers. These values allow software to discover the size and structure of the endpoint address space without relying on hard-coded assumptions.
The endpoint configuration registers define the local MAC address used by the endpoint when exchanging frames with the openENOC network. Remote communication targets are described through a peer table, where each entry contains the MAC address of a remote peer, the offset of the corresponding virtual remote-memory region, the local memory base address, the remote memory base address, and the size of the region. This structure allows software to describe how local memory resources are related to remote memory regions visible through the endpoint.
The HAL supports two complementary access models. The first model is a software-visible AXI4-Stream access path exposed through source and sink register files. The source register file allows software to provide stream data words, assert the corresponding valid indication, and mark the last word of a frame. Software observes the ready status to determine when the endpoint can accept the next transfer. Conversely, the sink register file allows hardware to present received stream data to software, together with valid and last indications, while software acknowledges reception through the ready control field.
This CSR-mapped AXI4-Stream interface mirrors the basic AXI4-Stream handshake semantics in software-visible form. It is useful for low-bandwidth communication, diagnostics, initialization sequences, and simple software-driven frame exchange. The mechanism does not prescribe the internal implementation of the endpoint datapath; it only defines how stream-oriented transfers are exposed through the HAL.
The second access model is memory-oriented communication through the virtual remote-memory region. This region provides a software-visible address space representing memory associated with one or more remote peers. The mapping between a remote peer and its corresponding portion of the virtual memory space is defined by the peer configuration registers. Accesses to this region may be handled directly or used as the basis for DMA-driven transfers, depending on the configured DMA mode for the selected peer.
DMA behavior is controlled independently for each peer. When DMA operation is disabled, the peer entry remains configured but no automatic transfer is performed. In transparent mode, accesses to the virtual remote-memory region are translated into corresponding accesses to the remote peer memory region on a word-by-word basis. This mode is suitable when software requires a direct memory-mapped view of remote resources and when simple access semantics are preferred over bulk synchronization.
The endpoint HAL also supports mirrored transfer modes. In mirror-to-local mode, the local memory region is used as the software-visible representation of the remote peer memory, and the state of the remote memory region is fetched from the remote peer on demand or periodically. In mirror-to-remote mode, the remote memory region is used as the destination representation, and the state of the local memory region is sent to the remote peer on demand or periodically. These modes allow software to configure endpoint-to-endpoint memory synchronization without directly managing individual transport frames.
DMA transfers are initiated through a peer-specific request field. The corresponding status fields indicate whether the DMA engine is idle, whether the requested transfer has completed successfully, or whether an error has occurred. A typical software sequence therefore consists of configuring the peer address mapping, selecting the DMA mode, issuing a transfer request, and observing the idle, done, and error status indications until the operation reaches a terminal state.
The DMA control mechanism described here is local to endpoint management and should not be confused with Ethernet link-level or protocol-level flow control. Its purpose is to coordinate software-visible memory mappings and transfer requests with the internal endpoint datapath, DMA engine, and oETP processing logic.
The endpoint HAL therefore provides both a stream-oriented and a memory-oriented abstraction for communication with the openENOC network. The AXI4-Stream register interface offers a simple CSR-accessible path for direct frame exchange, while the peer table, virtual remote-memory region, and DMA controls provide a scalable mechanism for accessing and synchronizing memory resources across endpoints.
Register Definitions and CSR Memory Map
The SystemRDL source shown below defines the CSR structure of the openENOC Endpoint Interface. This source file is the maintained register specification used by the PeakRDL-based generation flow.
1// SPDX-FileCopyrightText: 2026 Enio Kaljic
2// SPDX-License-Identifier: CERN-OHL-S-2.0
3
4addrmap openenoc_endpoint #(
5 longint unsigned RMEM_TOTAL_DEPTH = 256,
6 longint unsigned NUM_OF_PEERS = 1,
7 string INST_NAME = "openenoc_endpoint"
8) {
9 name = INST_NAME;
10 desc = "Control and status register map for an openENOC Endpoint Interface instance.";
11
12 littleendian;
13 default accesswidth = 32;
14 default regwidth = 32;
15 default alignment = 4;
16 addressing = regalign;
17
18 reg info {
19 name = {INST_NAME, ".info"};
20 desc = "Read-only information register for this openENOC Endpoint Interface instance.";
21
22 regwidth = 64;
23
24 field {
25 name = {INST_NAME, ".info.rmem_total_depth[15:0]"};
26 desc = "Total depth of the shared memory region for all remote peers. This field reflects the RMEM_TOTAL_DEPTH parameter value.";
27
28 sw = r;
29 hw = r;
30 } rmem_total_depth[31:0] = RMEM_TOTAL_DEPTH;
31
32 field {
33 name = {INST_NAME, ".info.num_of_peers[31:16]"};
34 desc = "Number of remote peers supported by this openENOC Endpoint Interface instance. This field reflects the NUM_OF_PEERS parameter value.";
35
36 sw = r;
37 hw = r;
38 } num_of_peers[63:32] = NUM_OF_PEERS;
39 } info;
40
41 regfile config {
42 name = {INST_NAME, ".config"};
43 desc = "Configuration register file for this openENOC Endpoint Interface instance.";
44
45 reg mac_address {
46 name = {INST_NAME, ".config.mac_address"};
47 desc = "Local site 48-bit destination MAC address.";
48
49 regwidth = 64;
50
51 field {
52 name = {INST_NAME, ".config.mac_address.lo_word[31:0]"};
53 desc = "Lower 32 bits [31:0] of the 48-bit MAC address.";
54
55 sw = rw;
56 hw = rw;
57 } lo_word[31:0] = 0;
58
59 field {
60 name = {INST_NAME, ".config.mac_address.hi_word[47:32]"};
61 desc = "Upper 16 bits [47:32] of the 48-bit MAC address.";
62
63 sw = rw;
64 hw = rw;
65 } hi_word[47:32] = 0;
66 } mac_address;
67 } config;
68
69 regfile axis_if {
70 name = {INST_NAME, ".axis_if"};
71 desc = "Register file for the AXI4-Stream source and sink interfaces.";
72
73 regfile source {
74 name = {INST_NAME, ".axis_if.source"};
75 desc = "Register file for the AXI4-Stream source interface.";
76
77 reg data {
78 name = {INST_NAME, ".axis_if.source.data"};
79 desc = "Data register for the AXI4-Stream source interface.";
80
81 field {
82 name = {INST_NAME, ".axis_if.source.data.tdata[31:0]"};
83 desc = "32-bit data value for the AXI4-Stream source interface.";
84
85 sw = rw;
86 hw = r;
87 } tdata[31:0] = 0;
88 } data;
89
90 reg control {
91 name = {INST_NAME, ".axis_if.source.control"};
92 desc = "Control register for the AXI4-Stream source interface.";
93
94 field {
95 name = {INST_NAME, ".axis_if.source.control.tvalid"};
96 desc = "Indicates that the AXI4-Stream source interface has valid data to send. This field is a single-pulse register that is automatically cleared back to zero after being written.";
97
98 singlepulse = true;
99 sw = rw;
100 hw = r;
101 } tvalid[0:0] = 0;
102
103 field {
104 name = {INST_NAME, ".axis_if.source.control.tlast"};
105 desc = "Indicates the last data word of a frame on the AXI4-Stream source interface.";
106
107 sw = rw;
108 hw = r;
109 } tlast[8:8] = 0;
110 } control;
111
112 reg status {
113 name = {INST_NAME, ".axis_if.source.status"};
114 desc = "Status register for the AXI4-Stream source interface.";
115
116 field {
117 name = {INST_NAME, ".axis_if.source.status.tready"};
118 desc = "Indicates that the destination AXI4-Stream interface is ready to receive data.";
119
120 sw = r;
121 hw = w;
122 } tready[0:0] = 0;
123 } status;
124 } source;
125
126 regfile sink {
127 name = {INST_NAME, ".axis_if.sink"};
128 desc = "Register file for the AXI4-Stream sink interface.";
129
130 reg data {
131 name = {INST_NAME, ".axis_if.sink.data"};
132 desc = "Data register for the AXI4-Stream sink interface.";
133
134 field {
135 name = {INST_NAME, ".axis_if.sink.data.tdata[31:0]"};
136 desc = "32-bit data value for the AXI4-Stream sink interface.";
137
138 sw = r;
139 hw = w;
140 } tdata[31:0];
141 } data;
142
143 reg control {
144 name = {INST_NAME, ".axis_if.sink.control"};
145 desc = "Control register for the AXI4-Stream sink interface.";
146
147 field {
148 name = {INST_NAME, ".axis_if.sink.control.tready"};
149 desc = "Indicates that the AXI4-Stream sink interface is ready to receive next data transfer.";
150
151 singlepulse = true;
152 sw = w;
153 hw = r;
154 } tready[0:0] = 0;
155 } control;
156
157 reg status {
158 name = {INST_NAME, ".axis_if.sink.status"};
159 desc = "Status register for the AXI4-Stream sink interface.";
160
161 field {
162 name = {INST_NAME, ".axis_if.sink.status.tvalid"};
163 desc = "Indicates that the AXI4-Stream sink interface has valid data to receive.";
164
165 sw = r;
166 hw = w;
167 } tvalid[0:0];
168
169 field {
170 name = {INST_NAME, ".axis_if.sink.status.tlast"};
171 desc = "Indicates the last data word of a frame on the AXI4-Stream sink interface.";
172
173 sw = r;
174 hw = w;
175 } tlast[8:8];
176 } status;
177 } sink;
178 } axis_if;
179
180 regfile peers {
181 name = {INST_NAME, ".peers"};
182 desc = "Register file for remote peer configuration and memory region information.";
183
184 regfile entry {
185 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1]"};
186 desc = "Register file for a single remote peer configuration and memory region information.";
187
188 reg mac_address {
189 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].mac_address"};
190 desc = "Remote peer 48-bit destination MAC address.";
191
192 regwidth = 64;
193
194 field {
195 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].mac_address.lo_word[31:0]"};
196 desc = "Lower 32 bits [31:0] of the 48-bit MAC address.";
197
198 sw = rw;
199 hw = rw;
200 } lo_word[31:0];
201
202 field {
203 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].mac_address.hi_word[47:32]"};
204 desc = "Upper 16 bits [47:32] of the 48-bit MAC address.";
205
206 sw = rw;
207 hw = rw;
208 } hi_word[47:32];
209 } mac_address;
210
211 reg rmem_address {
212 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].rmem_address"};
213 desc = "Address offset of the virtual memory region corresponding to the remote peer's memory.";
214
215 field {
216 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].rmem_address.offset[31:0]"};
217 desc = "Word-aligned 32-bit address offset of the virtual memory region corresponding to the remote peer's memory.";
218
219 sw = rw;
220 hw = r;
221 } offset[31:0];
222 } rmem_address;
223
224 reg local_address {
225 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].local_address"};
226 desc = "Start address of the local memory region for DMA transfers.";
227
228 field {
229 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].local_address.base[31:0]"};
230 desc = "Word-aligned 32-bit start address of the local memory region for DMA transfers.";
231
232 sw = rw;
233 hw = r;
234 } base[31:0];
235 } local_address;
236
237 reg remote_address {
238 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].remote_address"};
239 desc = "Start address of the remote peer's memory region.";
240
241 field {
242 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].remote_address.base[31:0]"};
243 desc = "Word-aligned 32-bit start address of the remote peer's memory region.";
244
245 sw = rw;
246 hw = r;
247 } base[31:0];
248 } remote_address;
249
250 reg size {
251 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].size"};
252 desc = "Size of the remote peer's memory region.";
253
254 field {
255 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].size.bytes[31:0]"};
256 desc = "32-bit size of the remote peer's memory region in bytes.";
257
258 sw = rw;
259 hw = r;
260 } bytes[31:0];
261 } size;
262
263 reg dma {
264 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma"};
265 desc = "DMA configuration and control for the remote peer.";
266
267 field {
268 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma.mode[1:0]"};
269 desc = "
270 DMA mode for transfers to/from the remote peer:<ul>
271 <li>0: DMA transfers to/from the remote peer are disabled.</li>
272 <li>1: DMA transfers to/from the remote peer are enabled in transparent mode, where accesses to the virtual memory region are directly translated to corresponding accesses to the remote peer's memory region (transactions are word-by-word, i.e., per virtual memory access).</li>
273 <li>2: DMA transfers to/from the remote peer are enabled in mirror-to-local mode, where the local memory region is used instead of the virtual memory region. The state of the remote peer's memory region (remote_address, size) is fetched from the remote peer on demand or periodically.</li>
274 <li>3: DMA transfers to/from the remote peer are enabled in mirror-to-remote mode, where the remote memory region is used instead of the virtual memory region. The state of the local peer's memory region (local_address, size) is sent to the remote peer on demand or periodically.</li>
275 </ul>
276 ";
277
278 sw = rw;
279 hw = r;
280 } mode[1:0];
281
282 field {
283 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma.request[8:8]"};
284 desc = "Writing a 1 to this field initiates a DMA transfer to/from the remote peer. This field is a single-pulse register that is automatically cleared back to zero after being written.";
285
286 singlepulse = true;
287 sw = rw;
288 hw = r;
289 } request[8:8] = 0;
290
291 field {
292 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma.idle[16:16]"};
293 desc = "Indicates whether the DMA transfer to/from the remote peer is idle. A value of 1 indicates that the DMA transfer is idle, while a value of 0 indicates that the DMA transfer is in progress.";
294
295 sw = r;
296 hw = w;
297 } idle[16:16];
298
299 field {
300 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma.done[24:24]"};
301 desc = "Indicates whether the DMA transfer to/from the remote peer has been successful. A value of 1 indicates that the DMA transfer has completed successfully, while a value of 0 indicates that the DMA transfer is still in progress or has encountered an error.";
302
303 sw = r;
304 hw = w;
305 } done[24:24];
306
307 field {
308 name = {INST_NAME, ".peers.entry[0..NUM_OF_PEERS-1].dma.error[25:25]"};
309 desc = "Indicates whether the DMA transfer to/from the remote peer has encountered an error. A value of 1 indicates an error, while a value of 0 indicates no error.";
310
311 sw = r;
312 hw = w;
313 } error[25:25];
314 } dma;
315 } entry[NUM_OF_PEERS];
316 } peers;
317
318 external mem rmem {
319 name = "rmem";
320 desc = "Virtual memory region for all remote peers, with offsets and sizes defined in the peers regfile.";
321 mementries = RMEM_TOTAL_DEPTH;
322 memwidth = 32;
323 } rmem;
324};
The openENOC Endpoint Interface CSR memory map and detailed register documentation are derived directly from this SystemRDL specification. The generated CSR documentation provides the corresponding human-readable description of the register hierarchy, address offsets, field layouts, access permissions, reset values, and associated register semantics.
The complete generated CSR documentation is available in openenoc_endpoint address map.
Summary
This document defines the HAL architecture and CSR organization for the openENOC Switch and the openENOC Endpoint Interface.
The HAL establishes a consistent software-visible programming model based on memory-mapped Control and Status Registers, while the CSR specification provides the authoritative description of hardware/software interactions. Together, these mechanisms form the foundation for software development, system integration, and verification activities within the openENOC project.