ab_riscv_interpreter/
zkr.rs1#[cfg(test)]
4mod tests;
5pub mod zkr_helpers;
6
7use crate::zicsr::zicsr_helpers;
8use crate::{
9 CsrError, Csrs, ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands,
10 ExecutionError, ExecutionResult, FetchInstructionResult, InstructionFetcher,
11 OpaqueThreadedExecutionResult, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
12 ThreadedExecutableInstruction, ThreadedExecutionResult,
13};
14use ab_riscv_macros::instruction_execution;
15use ab_riscv_primitives::prelude::*;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ZkrSeedPoll {
21 Bist,
26 Wait,
31 Es16(u16),
34 Dead,
38}
39
40pub const trait ZkrSeedSource {
44 fn poll_seed(&mut self) -> ZkrSeedPoll;
46}
47
48const impl<T> ZkrSeedSource for &mut T
50where
51 T: [const] ZkrSeedSource,
52{
53 #[inline(always)]
54 fn poll_seed(&mut self) -> ZkrSeedPoll {
55 T::poll_seed(self)
56 }
57}
58
59#[instruction_execution]
60const impl<Reg> ExecutableInstructionOperands for ZkrInstruction<Reg> where Reg: [const] Register {}
61
62#[instruction_execution]
63const impl<Reg, Env> ExecutableInstructionCsr<Env> for ZkrInstruction<Reg>
64where
65 Reg: [const] Register,
66 Env: [const] ZkrSeedSource,
67{
68 #[inline(always)]
74 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
75 fn prepare_csr_read(
76 _env: &Env,
77 csr_index: u16,
78 will_write: bool,
79 raw_value: Reg::Type,
80 output_value: &mut Reg::Type,
81 ) -> Result<bool, CsrError> {
82 if csr_index == SEED_CSR_INDEX {
83 if will_write {
84 *output_value = raw_value;
85 Ok(true)
86 } else {
87 Err(CsrError::IllegalRead { csr_index })
88 }
89 } else {
90 Ok(false)
91 }
92 }
93
94 #[inline(always)]
98 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
99 fn prepare_csr_write(
100 env: &mut Env,
101 csr_index: u16,
102 write_value: Reg::Type,
103 output_value: &mut Reg::Type,
104 ) -> Result<bool, CsrError> {
105 let _: Reg::Type = write_value;
107
108 if csr_index == SEED_CSR_INDEX {
109 *output_value = zkr_helpers::encode_seed_poll::<Reg>(env.poll_seed());
110 Ok(true)
111 } else {
112 Ok(false)
113 }
114 }
115}
116
117#[instruction_execution]
118const impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
119 for ZkrInstruction<Reg>
120where
121 Reg: Register,
122 Env: [const] ZkrSeedSource,
123{
124 #[inline(always)]
125 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
126 fn execute(
127 self,
128 Rs1Rs2OperandValues {
129 rs1_value,
130 rs2_value: _,
131 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
132 _regs: &mut Regs,
133 env: &mut Env,
134 _memory: &mut Memory,
135 _program_counter: &mut PC,
136 ) -> ExecutionResult<Self::Reg> {
137 ExecutionResult::ContinueNoWrite
138 }
139}