ultrasonic/isa/
core.rs

1// UltraSONIC: transactional execution layer with capability-based memory access for zk-AluVM
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Designed in 2019-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
6// Written in 2024-2025 by Dr Maxim Orlovsky <orlovsky@ubideco.org>
7//
8// Copyright (C) 2019-2024 LNP/BP Standards Association, Switzerland.
9// Copyright (C) 2024-2025 Laboratories for Ubiquitous Deterministic Computing (UBIDECO),
10//                         Institute for Distributed and Cognitive Systems (InDCS), Switzerland.
11// Copyright (C) 2019-2025 Dr Maxim Orlovsky.
12// All rights under the above copyrights are reserved.
13//
14// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
15// in compliance with the License. You may obtain a copy of the License at
16//
17//        http://www.apache.org/licenses/LICENSE-2.0
18//
19// Unless required by applicable law or agreed to in writing, software distributed under the License
20// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
21// or implied. See the License for the specific language governing permissions and limitations under
22// the License.
23
24use core::fmt::{self, Debug, Formatter};
25
26use aluvm::alu::{CoreExt, NoExt, Register, Supercore};
27use aluvm::{GfaConfig, GfaCore, RegE};
28
29#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
30enum Io {
31    #[display(":in")]
32    Input,
33    #[display(":out")]
34    Output,
35}
36
37#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
38enum Mem {
39    #[display(":readonce")]
40    ReadOnce,
41    #[display(":immutable")]
42    AppendOnly,
43}
44
45#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
46pub struct IoCat {
47    io: Io,
48    mem: Mem,
49}
50
51impl IoCat {
52    pub const IN_RO: Self = Self { io: Io::Input, mem: Mem::ReadOnce };
53    pub const IN_AO: Self = Self { io: Io::Input, mem: Mem::AppendOnly };
54    pub const OUT_RO: Self = Self { io: Io::Output, mem: Mem::ReadOnce };
55    pub const OUT_AO: Self = Self { io: Io::Output, mem: Mem::AppendOnly };
56
57    pub const fn index(&self) -> usize {
58        match (self.io, self.mem) {
59            (Io::Input, Mem::ReadOnce) => 0,
60            (Io::Input, Mem::AppendOnly) => 1,
61            (Io::Output, Mem::ReadOnce) => 2,
62            (Io::Output, Mem::AppendOnly) => 3,
63        }
64    }
65}
66
67#[derive(Copy, Clone, Eq, PartialEq)]
68pub struct UsonicCore {
69    /// State value iterator positions
70    pub(super) ui: [u16; 4],
71
72    pub(super) gfa: GfaCore,
73}
74
75impl Debug for UsonicCore {
76    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
77        let (sect, reg, val, reset) = if f.alternate() {
78            ("\x1B[0;4;1m", "\x1B[0;1m", "\x1B[0;32m", "\x1B[0m")
79        } else {
80            ("", "", "", "")
81        };
82
83        writeln!(f)?;
84        writeln!(f, "{sect}U-regs:{reset}")?;
85        write!(f, "{reg}UI1{reset} {val}{}{reset}  ", self.ui[IoCat::IN_RO.index()])?;
86        write!(f, "{reg}UI2{reset} {val}{}{reset}  ", self.ui[IoCat::IN_AO.index()])?;
87        write!(f, "{reg}UI3{reset} {val}{}{reset}  ", self.ui[IoCat::OUT_RO.index()])?;
88        writeln!(f, "{reg}UI4{reset} {val}{}{reset}  ", self.ui[IoCat::OUT_AO.index()])?;
89        writeln!(f)
90    }
91}
92
93impl CoreExt for UsonicCore {
94    type Reg = RegE;
95    type Config = GfaConfig;
96
97    fn with(config: Self::Config) -> Self { UsonicCore { ui: [0; 4], gfa: GfaCore::with(config) } }
98
99    fn get(&self, reg: Self::Reg) -> Option<<Self::Reg as Register>::Value> { self.gfa.get(reg) }
100
101    fn clr(&mut self, reg: Self::Reg) { self.gfa.clr(reg) }
102
103    fn put(&mut self, reg: Self::Reg, val: Option<<Self::Reg as Register>::Value>) {
104        self.gfa.put(reg, val)
105    }
106
107    fn reset(&mut self) {
108        self.gfa.reset();
109        self.ui = [0; 4];
110    }
111}
112
113impl Supercore<GfaCore> for UsonicCore {
114    fn subcore(&self) -> GfaCore { self.gfa }
115
116    fn merge_subcore(&mut self, subcore: GfaCore) { self.gfa = subcore; }
117}
118
119impl Supercore<NoExt> for UsonicCore {
120    fn subcore(&self) -> NoExt { NoExt }
121
122    fn merge_subcore(&mut self, _subcore: NoExt) {}
123}