OR-1 dataflow CPU sketch
1from pathlib import Path
2
3import pytest
4from hypothesis import strategies as st
5from lark import Lark
6
7from cm_inst import ArithOp, FrameOp, LogicOp, MemOp, Port, RoutingOp
8from tokens import CMToken, DyadToken, FrameControlToken, MonadToken, PELocalWriteToken, SMToken
9
10GRAMMAR_PATH = Path(__file__).parent.parent / "dfasm.lark"
11
12uint16 = st.integers(min_value=0, max_value=0xFFFF)
13int16 = st.integers(min_value=-32768, max_value=32767)
14shift_amount = st.integers(min_value=0, max_value=15)
15
16arith_dyadic_ops = st.sampled_from([ArithOp.ADD, ArithOp.SUB])
17arith_monadic_ops = st.sampled_from([ArithOp.INC, ArithOp.DEC])
18shift_ops = st.sampled_from([ArithOp.SHL, ArithOp.SHR, ArithOp.ASR])
19logic_dyadic_ops = st.sampled_from([LogicOp.AND, LogicOp.OR, LogicOp.XOR])
20comparison_ops = st.sampled_from([LogicOp.EQ, LogicOp.LT, LogicOp.LTE, LogicOp.GT, LogicOp.GTE])
21branch_ops = st.sampled_from([RoutingOp.BREQ, RoutingOp.BRGT, RoutingOp.BRGE])
22switch_ops = st.sampled_from([RoutingOp.SWEQ, RoutingOp.SWGT, RoutingOp.SWGE])
23overflow_ops = st.sampled_from([RoutingOp.BROF, RoutingOp.SWOF])
24data_routing_ops = st.sampled_from([RoutingOp.SEL, RoutingOp.MRGE])
25
26
27@st.composite
28def dyad_token(draw, target: int = 0, offset: int | None = None, act_id: int | None = None) -> DyadToken:
29 return DyadToken(
30 target=target,
31 offset=draw(st.integers(min_value=0, max_value=63)) if offset is None else offset,
32 act_id=draw(st.integers(min_value=0, max_value=7)) if act_id is None else act_id,
33 data=draw(uint16),
34 port=draw(st.sampled_from(list(Port))),
35 )
36
37
38@st.composite
39def monad_token(draw, target: int = 0, offset: int | None = None, act_id: int | None = None) -> MonadToken:
40 return MonadToken(
41 target=target,
42 offset=draw(st.integers(min_value=0, max_value=63)) if offset is None else offset,
43 act_id=draw(st.integers(min_value=0, max_value=7)) if act_id is None else act_id,
44 data=draw(uint16),
45 inline=False,
46 )
47
48
49# SM ops: implemented for T1 are READ, WRITE, CLEAR, RD_INC, RD_DEC, CMP_SW, ALLOC, FREE, EXEC
50# Unimplemented: SET_PAGE, WRITE_IMM, RAW_READ, EXT
51sm_implemented_ops = [
52 MemOp.READ, MemOp.WRITE, MemOp.CLEAR, MemOp.RD_INC, MemOp.RD_DEC,
53 MemOp.CMP_SW, MemOp.ALLOC, MemOp.FREE, MemOp.EXEC
54]
55sm_all_ops = st.sampled_from(sm_implemented_ops)
56
57
58@st.composite
59def sm_token(draw, addr=None, op=None, data=None):
60 # By default, generate T1 addresses (below tier_boundary of 256)
61 # Tests that specifically need T0 addresses should pass them explicitly
62 _addr = draw(st.integers(min_value=0, max_value=255)) if addr is None else addr
63 _op = draw(sm_all_ops) if op is None else op
64 _data = draw(uint16) if data is None else data
65 ret = CMToken(target=0, offset=0, act_id=0, data=0)
66 return SMToken(
67 target=0,
68 addr=_addr,
69 op=_op,
70 flags=None,
71 data=_data,
72 ret=ret,
73 )
74
75
76@st.composite
77def sm_return_route(draw, target=0):
78 return CMToken(
79 target=target,
80 offset=draw(st.integers(min_value=0, max_value=63)),
81 act_id=draw(st.integers(min_value=0, max_value=7)),
82 data=0,
83 )
84
85
86@st.composite
87def pe_local_write_token(draw, target: int = 0, act_id: int | None = None) -> PELocalWriteToken:
88 return PELocalWriteToken(
89 target=target,
90 act_id=draw(st.integers(min_value=0, max_value=7)) if act_id is None else act_id,
91 region=draw(st.integers(min_value=0, max_value=1)),
92 slot=draw(st.integers(min_value=0, max_value=63)),
93 data=draw(uint16),
94 is_dest=draw(st.booleans()),
95 )
96
97
98@st.composite
99def frame_control_token(draw, target: int = 0, act_id: int | None = None) -> FrameControlToken:
100 return FrameControlToken(
101 target=target,
102 act_id=draw(st.integers(min_value=0, max_value=7)) if act_id is None else act_id,
103 op=draw(st.sampled_from(list(FrameOp))),
104 payload=draw(uint16),
105 )
106
107
108@pytest.fixture(scope="session")
109def parser():
110 """Get the dfasm parser."""
111 return Lark(
112 GRAMMAR_PATH.read_text(),
113 parser="earley",
114 propagate_positions=True,
115 )