OR-1 dataflow CPU sketch
1"""Opcode-to-category mapping for visual graph rendering.
2
3Maps each ALUOp/MemOp to a visual category and colour
4for the dataflow graph renderer.
5"""
6
7from __future__ import annotations
8
9from enum import Enum
10from typing import Union
11
12from cm_inst import ArithOp, LogicOp, MemOp, RoutingOp
13
14
15class OpcodeCategory(Enum):
16 ARITHMETIC = "arithmetic"
17 LOGIC = "logic"
18 COMPARISON = "comparison"
19 ROUTING = "routing"
20 MEMORY = "memory"
21 IO = "io" # reserved for future I/O ops (ior, iow, iorw) — not yet in asm/opcodes.py
22 CONFIG = "config"
23 STRUCTURE_MEMORY = "structure_memory"
24
25
26CATEGORY_COLOURS: dict[OpcodeCategory, str] = {
27 OpcodeCategory.ARITHMETIC: "#4a90d9",
28 OpcodeCategory.LOGIC: "#4caf50",
29 OpcodeCategory.COMPARISON: "#ff9800",
30 OpcodeCategory.ROUTING: "#9c27b0",
31 OpcodeCategory.MEMORY: "#ff5722",
32 OpcodeCategory.IO: "#009688",
33 OpcodeCategory.CONFIG: "#9e9e9e",
34 OpcodeCategory.STRUCTURE_MEMORY: "#795548",
35}
36
37
38_COMPARISON_OPS: frozenset[LogicOp] = frozenset({
39 LogicOp.EQ, LogicOp.LT, LogicOp.LTE, LogicOp.GT, LogicOp.GTE,
40})
41
42_CONFIG_ROUTING_OPS: frozenset[RoutingOp] = frozenset({
43 RoutingOp.CONST, RoutingOp.FREE_FRAME,
44})
45
46
47def categorise(op: Union[ArithOp, LogicOp, RoutingOp, MemOp]) -> OpcodeCategory:
48 """Categorise an opcode for visual rendering.
49
50 Maps each opcode to a visual category used by the graph renderer.
51 Handles special cases like LogicOp comparison ops and RoutingOp config ops.
52
53 Args:
54 op: An opcode enum value (ArithOp, LogicOp, RoutingOp, or MemOp)
55
56 Returns:
57 The OpcodeCategory for this opcode
58
59 Raises:
60 ValueError: If the opcode type is unknown
61 """
62 if isinstance(op, ArithOp):
63 return OpcodeCategory.ARITHMETIC
64 if isinstance(op, LogicOp):
65 if op in _COMPARISON_OPS:
66 return OpcodeCategory.COMPARISON
67 return OpcodeCategory.LOGIC
68 if isinstance(op, RoutingOp):
69 if op in _CONFIG_ROUTING_OPS:
70 return OpcodeCategory.CONFIG
71 return OpcodeCategory.ROUTING
72 if isinstance(op, MemOp):
73 return OpcodeCategory.MEMORY
74 raise ValueError(f"Unknown opcode type: {type(op).__name__}")