OR-1 dataflow CPU sketch
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <title>OR1 Monitor</title>
7 <style>
8 * {
9 margin: 0;
10 padding: 0;
11 box-sizing: border-box;
12 }
13
14 body {
15 font-family: system-ui, sans-serif;
16 height: 100vh;
17 display: flex;
18 flex-direction: column;
19 background: #191724;
20 color: #e0def4;
21 }
22
23 #toolbar {
24 padding: 8px 16px;
25 background: #26233a;
26 border-bottom: 1px solid #403d52;
27 display: flex;
28 align-items: center;
29 gap: 12px;
30 flex-wrap: wrap;
31 min-height: 50px;
32 }
33
34 #toolbar h1 {
35 font-size: 16px;
36 font-weight: 600;
37 margin-right: auto;
38 color: #e0def4;
39 }
40
41 #toolbar button {
42 background: #1f1d2e;
43 color: #e0def4;
44 border: 1px solid #403d52;
45 padding: 6px 12px;
46 border-radius: 4px;
47 cursor: pointer;
48 font-size: 12px;
49 white-space: nowrap;
50 }
51
52 #toolbar button:hover {
53 background: #403d52;
54 }
55
56 #layout-toggle {
57 background: #31748f;
58 border: none;
59 font-weight: 500;
60 color: #e0def4;
61 }
62
63 #layout-toggle:hover {
64 background: #286b82;
65 }
66
67 #toolbar input[type="text"],
68 #toolbar input[type="number"] {
69 background: #191724;
70 color: #e0def4;
71 border: 1px solid #403d52;
72 padding: 4px 8px;
73 border-radius: 4px;
74 font-size: 12px;
75 width: 80px;
76 }
77
78 #toolbar input[type="file"] {
79 display: none;
80 }
81
82 #toolbar label {
83 display: flex;
84 align-items: center;
85 gap: 4px;
86 font-size: 12px;
87 color: #908caa;
88 }
89
90 #sim-time {
91 font-family: monospace;
92 font-size: 12px;
93 color: #9ccfd8;
94 margin-left: 16px;
95 }
96
97 #finished-badge {
98 display: none;
99 background: #eb6f92;
100 color: #191724;
101 padding: 2px 8px;
102 border-radius: 3px;
103 font-size: 11px;
104 font-weight: 600;
105 margin-left: 8px;
106 }
107
108 #connection-status {
109 font-size: 11px;
110 margin-left: 12px;
111 color: #eb6f92;
112 }
113
114 #main-content {
115 display: flex;
116 flex: 1;
117 gap: 0;
118 overflow: hidden;
119 }
120
121 #graph {
122 flex: 2;
123 position: relative;
124 background: #191724;
125 }
126
127 #sidebar {
128 flex: 1;
129 max-width: 450px;
130 display: flex;
131 flex-direction: column;
132 background: #1f1d2e;
133 border-left: 1px solid #403d52;
134 overflow: hidden;
135 }
136
137 #event-log-section {
138 flex: 1;
139 display: flex;
140 flex-direction: column;
141 border-bottom: 1px solid #26233a;
142 overflow: hidden;
143 }
144
145 #event-log-header {
146 padding: 8px 12px;
147 background: #26233a;
148 border-bottom: 1px solid #403d52;
149 display: flex;
150 align-items: center;
151 gap: 8px;
152 font-size: 12px;
153 font-weight: 600;
154 color: #9ccfd8;
155 }
156
157 #event-log-controls {
158 display: flex;
159 gap: 8px;
160 padding: 6px 12px;
161 background: #26233a;
162 border-bottom: 1px solid #403d52;
163 }
164
165 #event-log-controls select {
166 background: #1f1d2e;
167 color: #e0def4;
168 border: 1px solid #403d52;
169 padding: 4px 8px;
170 border-radius: 3px;
171 font-size: 11px;
172 flex: 1;
173 }
174
175 #event-log {
176 flex: 1;
177 overflow-y: auto;
178 padding: 4px;
179 font-family: monospace;
180 font-size: 11px;
181 }
182
183 .event-entry {
184 padding: 6px 8px;
185 border-bottom: 1px solid #26233a;
186 cursor: pointer;
187 transition: background-color 0.15s;
188 }
189
190 .event-entry:hover {
191 background-color: #26233a;
192 }
193
194 #state-inspector-section {
195 flex: 1;
196 display: flex;
197 flex-direction: column;
198 overflow: hidden;
199 }
200
201 #state-inspector-header {
202 padding: 8px 12px;
203 background: #26233a;
204 border-bottom: 1px solid #403d52;
205 font-size: 12px;
206 font-weight: 600;
207 color: #f6c177;
208 }
209
210 #state-inspector {
211 flex: 1;
212 overflow-y: auto;
213 padding: 8px 12px;
214 font-family: monospace;
215 font-size: 10px;
216 }
217
218 #state-inspector h3 {
219 margin-top: 12px;
220 margin-bottom: 6px;
221 font-size: 12px;
222 color: #c4a7e7;
223 }
224
225 details {
226 margin-bottom: 8px;
227 }
228
229 summary {
230 cursor: pointer;
231 user-select: none;
232 padding: 4px;
233 border-radius: 3px;
234 color: #908caa;
235 }
236
237 summary:hover {
238 background: rgba(224, 222, 244, 0.05);
239 }
240
241 details[open] > summary {
242 margin-bottom: 4px;
243 color: #e0def4;
244 }
245
246 .toolbar-group {
247 display: flex;
248 align-items: center;
249 gap: 8px;
250 padding: 0 4px;
251 border-right: 1px solid #26233a;
252 }
253
254 .toolbar-group:last-child {
255 border-right: none;
256 }
257
258 .control-group {
259 display: flex;
260 align-items: center;
261 gap: 4px;
262 }
263
264 .control-group label {
265 font-size: 11px;
266 }
267
268 .control-group input {
269 width: 60px;
270 }
271
272 /* Scrollbar styling */
273 #event-log::-webkit-scrollbar,
274 #state-inspector::-webkit-scrollbar {
275 width: 8px;
276 }
277
278 #event-log::-webkit-scrollbar-track,
279 #state-inspector::-webkit-scrollbar-track {
280 background: #191724;
281 }
282
283 #event-log::-webkit-scrollbar-thumb,
284 #state-inspector::-webkit-scrollbar-thumb {
285 background: #403d52;
286 border-radius: 4px;
287 }
288
289 #event-log::-webkit-scrollbar-thumb:hover,
290 #state-inspector::-webkit-scrollbar-thumb:hover {
291 background: #524f67;
292 }
293 </style>
294</head>
295<body>
296 <!-- Toolbar -->
297 <div id="toolbar">
298 <h1>OR1 Monitor</h1>
299
300 <!-- File load group -->
301 <div class="toolbar-group">
302 <button id="load-button">Load File</button>
303 <input type="file" id="file-input" accept=".dfasm" />
304 </div>
305
306 <!-- Stepping controls -->
307 <div class="toolbar-group">
308 <button id="step-tick-button">Step Tick</button>
309 <button id="step-event-button">Step Event</button>
310 </div>
311
312 <!-- Run until -->
313 <div class="toolbar-group control-group">
314 <label for="run-until-input">Run Until:</label>
315 <input type="number" id="run-until-input" placeholder="0.0" step="0.1" />
316 <button id="run-until-button">Run</button>
317 </div>
318
319 <!-- Send token -->
320 <div class="toolbar-group control-group">
321 <label>Send:</label>
322 <input type="number" id="send-target" placeholder="PE" min="0" />
323 <input type="number" id="send-offset" placeholder="off" min="0" />
324 <input type="number" id="send-ctx" placeholder="ctx" min="0" />
325 <input type="number" id="send-data" placeholder="data" />
326 <button id="send-button">Send</button>
327 </div>
328
329 <!-- Inject token -->
330 <div class="toolbar-group control-group">
331 <label>Inject:</label>
332 <input type="number" id="inject-target" placeholder="PE" min="0" />
333 <input type="number" id="inject-offset" placeholder="off" min="0" />
334 <input type="number" id="inject-ctx" placeholder="ctx" min="0" />
335 <input type="number" id="inject-data" placeholder="data" />
336 <button id="inject-button">Inject</button>
337 </div>
338
339 <!-- Reset -->
340 <div class="toolbar-group">
341 <button id="reset-button">Reset</button>
342 </div>
343
344 <!-- Layout toggle -->
345 <div class="toolbar-group">
346 <button id="layout-toggle">Logical Layout</button>
347 </div>
348
349 <!-- Export -->
350 <div class="toolbar-group">
351 <button id="export-svg-button">Export SVG</button>
352 <button id="export-png-button">Export PNG</button>
353 <button id="copy-png-button">Copy PNG</button>
354 </div>
355
356 <!-- Status -->
357 <div style="margin-left: auto; display: flex; align-items: center; gap: 12px;">
358 <span id="sim-time">t=0.000</span>
359 <span id="finished-badge">FINISHED</span>
360 <span id="connection-status" style="font-size: 11px;">Connecting...</span>
361 </div>
362 </div>
363
364 <!-- Main content area -->
365 <div id="main-content">
366 <!-- Graph panel -->
367 <div id="graph"></div>
368
369 <!-- Right sidebar -->
370 <div id="sidebar">
371 <!-- Event log section -->
372 <div id="event-log-section">
373 <div id="event-log-header">Event Log</div>
374 <div id="event-log-controls">
375 <select id="filter-component">
376 <option value="">All Components</option>
377 </select>
378 <select id="filter-type">
379 <option value="">All Events</option>
380 <option value="Matched">Matched</option>
381 <option value="Executed">Executed</option>
382 <option value="TokenReceived">TokenReceived</option>
383 <option value="CellWritten">CellWritten</option>
384 <option value="DeferredRead">DeferredRead</option>
385 <option value="Emitted">Emitted</option>
386 <option value="TokenStored">TokenStored</option>
387 </select>
388 </div>
389 <div id="event-log"></div>
390 </div>
391
392 <!-- State inspector section -->
393 <div id="state-inspector-section">
394 <div id="state-inspector-header">State Inspector</div>
395 <div id="state-inspector"></div>
396 </div>
397 </div>
398 </div>
399
400 <script type="module" src="dist/bundle.js"></script>
401</body>
402</html>