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
24
25CATEGORY_COLOURS: dict[OpcodeCategory, str] = {
26 OpcodeCategory.ARITHMETIC: "#4a90d9",
27 OpcodeCategory.LOGIC: "#4caf50",
28 OpcodeCategory.COMPARISON: "#ff9800",
29 OpcodeCategory.ROUTING: "#9c27b0",
30 OpcodeCategory.MEMORY: "#ff5722",
31 OpcodeCategory.IO: "#009688",
32 OpcodeCategory.CONFIG: "#9e9e9e",
33}
34
35
36_COMPARISON_OPS: frozenset[LogicOp] = frozenset({
37 LogicOp.EQ, LogicOp.LT, LogicOp.LTE, LogicOp.GT, LogicOp.GTE,
38})
39
40_CONFIG_ROUTING_OPS: frozenset[RoutingOp] = frozenset({
41 RoutingOp.CONST, RoutingOp.FREE_CTX,
42})
43
44
45def categorise(op: Union[ArithOp, LogicOp, RoutingOp, MemOp]) -> OpcodeCategory:
46 """Categorise an opcode for visual rendering.
47
48 Maps each opcode to a visual category used by the graph renderer.
49 Handles special cases like LogicOp comparison ops and RoutingOp config ops.
50
51 Args:
52 op: An opcode enum value (ArithOp, LogicOp, RoutingOp, or MemOp)
53
54 Returns:
55 The OpcodeCategory for this opcode
56
57 Raises:
58 ValueError: If the opcode type is unknown
59 """
60 if isinstance(op, ArithOp):
61 return OpcodeCategory.ARITHMETIC
62 if isinstance(op, LogicOp):
63 if op in _COMPARISON_OPS:
64 return OpcodeCategory.COMPARISON
65 return OpcodeCategory.LOGIC
66 if isinstance(op, RoutingOp):
67 if op in _CONFIG_ROUTING_OPS:
68 return OpcodeCategory.CONFIG
69 return OpcodeCategory.ROUTING
70 if isinstance(op, MemOp):
71 return OpcodeCategory.MEMORY
72 raise ValueError(f"Unknown opcode type: {type(op).__name__}")