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 ExecutableInstructionResult, ExecutionError, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
11};
12use ab_riscv_macros::instruction_execution;
13use ab_riscv_primitives::prelude::*;
14use core::marker::Destruct;
15use core::ops::ControlFlow;
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
48#[instruction_execution]
49const impl<Reg> ExecutableInstructionOperands for ZkrInstruction<Reg> where Reg: [const] Register {}
50
51#[instruction_execution]
52const impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
53 for ZkrInstruction<Reg>
54where
55 Reg: [const] Register,
56 ExtState: [const] ZkrSeedSource,
57 CustomError: [const] Destruct,
58{
59 #[inline(always)]
65 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
66 fn prepare_csr_read(
67 _ext_state: &ExtState,
68 csr_index: u16,
69 will_write: bool,
70 raw_value: Reg::Type,
71 output_value: &mut Reg::Type,
72 ) -> Result<bool, CsrError<CustomError>> {
73 if csr_index == SEED_CSR_INDEX {
74 if will_write {
75 *output_value = raw_value;
76 Ok(true)
77 } else {
78 Err(CsrError::IllegalRead { csr_index })
79 }
80 } else {
81 Ok(false)
82 }
83 }
84
85 #[inline(always)]
89 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic(const))]
90 fn prepare_csr_write(
91 ext_state: &mut ExtState,
92 csr_index: u16,
93 write_value: Reg::Type,
94 output_value: &mut Reg::Type,
95 ) -> Result<bool, CsrError<CustomError>> {
96 let _: Reg::Type = write_value;
98
99 if csr_index == SEED_CSR_INDEX {
100 *output_value = zkr_helpers::encode_seed_poll::<Reg>(ext_state.poll_seed());
101 Ok(true)
102 } else {
103 Ok(false)
104 }
105 }
106}
107
108#[instruction_execution]
109const impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
110 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
111 for ZkrInstruction<Reg>
112where
113 Reg: Register,
114 ExtState: [const] ZkrSeedSource,
115{
116 #[inline(always)]
117 fn execute(
119 self,
120 Rs1Rs2OperandValues {
121 rs1_value,
122 rs2_value: _,
123 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
124 _regs: &mut Regs,
125 ext_state: &mut ExtState,
126 _memory: &mut Memory,
127 _program_counter: &mut PC,
128 _system_instruction_handler: &mut InstructionHandler,
129 ) -> ExecutableInstructionResult<(), Self, CustomError> {
130 Ok(ControlFlow::Continue(Default::default()))
131 }
132}