OR-1 dataflow CPU sketch

⚠ SUPERSEDED — This was an early syntax sketch. The canonical grammar is dfasm.lark (Lark/Earley parser, 38+ tests in tests/test_parser.py). Mnemonics, naming conventions, and some semantics have diverged from this sketch. Preserved for historical context and design rationale only.

Ops#

CM tokens#

Type 1 (0b00)

  • token carries operand for a dyadic (two-input) instruction. requires matching store lookup. Type 2 (0b01)
  • token carries operand for a monadic (single-input) instruction. bypasses matching store.

Fields#

  • offset instruction slot
  • ctx execution context (data) slot
  • port L/R operand discriminator (dyadic)
  • gen generation counter (dyadic)
  • inl|wid inline flag on monadic ops, width flag on dyadic ops
  • data

ALU - Arithmetic Logic Unit (Control Memory module)#

  • 5-bit opcode (initial)
  • opcodes not present on bus except as part of cfg token data words

Arithmetic#

  • add
  • sub
  • inc (monadic)
  • dec (monadic)

NOTE: could we re-use the same opcodes for add/sub and inc/dec? everything about them is essentially the same except for dyadic/monadic

Shifts (monadic)

  • shiftl - Shift A left by N+1 bits. N from IRAM immediate field (1-8 allow for shifting of a full byte's width)
  • shiftr - Logical shift A right by N+1 bits. Zero-fill. N from immediate.
  • ashftr - Arithmetic shift A right by N bits. Sign-extend. N from immediate. (NOTE: implementation uses shl/shr/asr mnemonics — see alu-and-output-design.md)

Logical#

  • and
  • or
  • xor
  • not (monadic)

Comparison

  • eq
  • lt (do we want explicit signed/unsigned?)
  • lte
  • gt
  • gte

Routing/switching/branching#

All of these have perhaps odd wire semantics (see alu-and-output-design.md)

  • br(eq/gt/ge/of/ty) - branch plus continue|local bit
  • sw(eq/gt/ge/of/ty) - branch plus output enable
  • gate - pass or suppress
  • sel
  • merge

Data (all monadic)#

  • pass
  • const - constant load
  • free_ctx - dealloc context slot, no data output

System (Type 4)#

PE_id bits repurposed as subtype

iop

  • r
  • w
  • rw fields:
  • dest
  • addr|payload1
  • data|payload2 cfg
  • load_inst
  • fields:
    • dest
    • addr
    • data_l
    • data_h
    • ...chainable (data_l, data_h) to enable efficient loading of sequential addresses
  • route_set
  • fields:
    • dest
    • data (address mapping)

plus 2 reserved

MLU - Memory Logic Unit (Structure Memory module)#

Type 3 (0b10) token

  • 3-4 bit ext opcode + 9-8 bit internal addr
  • 4+ bit internal opcode + 12-bit internal addr

Fields#

  • SM id
  • opcode
  • flags (in extended mode)
  • data
  • return route

Syntax#

@output <| op L, R
; or 
op L, R |> @out1, @out2 

direction doesn't dictate number of outputs direction could dictate strong/weak connections

  • @name refers to a node
  • can be chained with | to manually specify a PE (e.g. @sum|pe0 )
  • opcode or node can be chained with : to manually specify an iram addr or context slot (e.g. sub:0x02) or L|R
  • NO spaces allowed in chains
  • $name refers to a function/subroutine/subgraph label, same rules as above
  • alternatively an opcode plus any const arg can be labeled as: &label <| op, arg
  • ; for comments, as is tradition, this is ASM
  • named args for clarity are allowed
@serial <| r dest=0x45, addr=0x91, data=0x43

function definition:

$fib |> {
  &const_n <| const, 10
  &sub1 <| sub
  &sub2 <| sub
  &branch <| switch
  
  &const_n |> &branch:L
  &const_n |> &sub1:L
  &const_n |> &sub1:R
  &const_n |> &sub2:R
  &sub1 |> &recurse_a:L
  ; ...
}

for initial data:

  • if it should start resident in SM, use = with a name or label expression
@hello = #str "hello"
  • # denotes a macro, (here, 'str') which expands the above to something more like
@hello|sm0:0 = 0x05 ; length
@hello|sm0:1 = 'h','e' ; 16-bit data slots can hold 2 utf8/ascii chars
@hello|sm0:2 = 'l','l' 
...

loading:

  • initial program loading happens via a generated (or explicit) series of cfg and sm instructions

inst_defs and adjacent edges are collected and transformed into a series of load_inst calls